Reputation: 457
I'm reading Computer Systems: A Programmer's Perspective, and I came across the following C files:
Foo.c:
void f(void);
int x = 15213;
int y = 15212;
int main()
{
f();
printf("x = 0x%x y = 0x%x \n", x, y);
return 0;
}
Bar.c:
double x;
void f()
{
x = -0.0;
}
which are compiled with gcc -o foobar foo.c bar.c and gives the following output:
x = 0x0 y = 0x80000000
Wow. So since int is 4 bytes and double is 8 bytes (on my system anyway) and the strong symbol of x is in Foo.c, x is assigned the hex representation of -0.0, which in turn overwrites y too!
So I'd like to know more about this. How come the standard C type safeguards don't come into play here? Is 0x0000000080000000 blindly written to where x is stored in the ELF, and y happens to be next to it and gets overwritten? Feel free to be as detailed as possible.
Upvotes: 2
Views: 2784
Reputation: 19864
You are violating "One definition rule"
An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.
which leads to undefined behavior.Basically you have 2 definitions for the object x
and declaration also varies.The standard says
All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
Note:
%x
is used to print out the unsigned int in the unsigned hexadecimal format and trying to print out a negative number using %x
leads to undefined behavior.
Using wrong format specifier leads to undefined behavior.
Upvotes: 3
Reputation: 4041
Have you noticed that this warning is coming when you are compiling.
/usr/bin/ld: Warning: alignment 4 of symbol `x' in /tmp/cciNZgVG.o is smaller than 8 in /tmp/cc8pYw6O.o
It is undefined behavior. Don't ignore the warnings. And it producing the answer based on the value you are assigning.
Upvotes: 3