ta0kira is exactly right. Because
test() is implicitly declared, the older GCC uses the int type for all parameters, just like the C standards dictate. x86_64 is an LP64 platform, where long and pointers are 64-bit, but ints are 32-bit. (If you use the
-m32 option for GCC, it'll compile normal 32-bit x86 code; on 64-bit distributions the default is
-m64 which will compile 64-bit code.)
Thus, the function will receive an invalid pointer to
a, unless the address of
a has all zeros in the upper 32 bits. You can print the address of a in
main (in hexadecimal) with e.g.
Code:
printf("a is at %p\n", (void *)(&a));
and in the test function with e.g.
Code:
printf("a is at %p\n", (void *)a);
if you wish to check this for yourself.
Newer GCC versions seem to promote the pointer parameters to long (which is always sufficiently large integer type to hold the pointer) when using an undeclared function. To reproduce the problem on later GCCs too, you'll need to e.g. rename
test to
test2 and use an wrapper function to reproduce the previous behaviour:
Code:
void test(int p)
{
printf("Pointer is %x\n", p);
test2((int *)p);
}
If you had compiled your test program with warnings enabled, you'd have noticed the
Code:
warning: implicit declaration of function ‘test’
To fix this, either add a proper declaration for the test function, or just define it prior to using it. Order is important in C.
Whenever you have problems with your code, especially segfaults, you should first compile with full warnings (use the
-Wall option for GCC), and fix the warnings first. Only in rare cases are the warnings bogus.
Nominal Animal