Re: Help wanted on some source codes



slebetman@xxxxxxxxx wrote:
Old Wolf wrote:
Becker wrote:

1.===========================================
/* a.c */
int x;
int y;

void main()
{
    f();
    printf("%x %x\n", x, y);
}

/* b.c */
double x;

void f()
{
    x = -0.0;
}
All of your programs have undefined behaviour because there
are two variables called 'x' with external linkage.


The programs are rubbish of course. But wouldn't the file scope of x mean that function f() is actually refering to the double x instead of the int x?

Nope, because technically, there's no difference between the two.

First of all, this program is in violation of:

6.9-5 "If an identifier declared with external linkage is used in an expression [..], somewhere in the entire program there shall be exactly one external definition for the identifier; [..]"

But suppose one of these was an "extern" declaration instead, so there was only one definition. Then we get:

6.2.2-2 "In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function."

So the "int x" and "double x" must be the same object. But of course that's not possible, and we are violating:

6.2.7-2 "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."

Needless to say, int and double are not compatible types.

Now, in *practice*, a compiler will indeed treat the 'x' in a.c and the 'x' in b.c as different objects within their respective scopes, compile the units as such, and then the linker will either notice a conflict (best case), create two separate objects (suboptimal but not completely awful case), or not notice anything at all and happily merge the storage for these incompatible objects (worst but unfortunately also most likely case).

Try this: assign some nontrivial value to 'x' in 'f', try to compile and link the program, then run it if this works. You should see the value of the double (partially) reinterpreted as an int. Say hi to the nasal demons for me when you do this.

This notwithstanding, a platform would actually be allowed to format your harddisk immediately after parsing both a.c and b.c, without paying any consideration to scope. The behavior is undefined; scope is irrelevant.

S.
.



Relevant Pages

  • Re: Vigenere Cipher
    ... The fact that stats() is in Polish and that you haven't ... This declaration as good as nothing. ... > void deszyfruj(); ... Better spell it out: int main. ...
    (comp.lang.c)
  • Re: wits end
    ... The keyword "void" is none of these. ... arguments, and then returned a value of type "int *", one had to ... However, ANSI C had to permit the old-style non-prototype declaration, ... number of arguments, so hope the programmer gets it right", how ...
    (comp.lang.c)
  • Re: Confusion in ANSI Cs function concepts
    ... is no function declaration corresponding to the function call and the ... should assume a declaration with an int return type. ... the compiler will assume that fun is a function returning int ... in the above case the return type is mentioned as void *. ...
    (comp.lang.c)
  • Re: Defining variable in C header file related doubt
    ... Other people have told you that it's tentative because the standard defines it to be tentative, and have cited the relevant clause. ... If there are no other definitions, then 'g' will have external linkage and be zero-initialized. ... static int g; ... if a following declaration were to say: ...
    (comp.lang.c)
  • Re: Function declaration (was: copy an istringstream)
    ... > nothing and returning int as parameter. ... > are ignored (as is in the case in our first parameter), ... Unfortunately C++ doesn't require void in function declaration. ... It seems that void foo2, int) is more intuitive declaration. ...
    (comp.lang.cpp)