Потому что вы помещаете obj
в стек. Другими словами, вы помещаете туда целые числа 10 и 7, и одно из них используется для %d
, другое для %p
. Фактический указатель вообще не используется.
Измените строку на:
printf("%d %d -- %p\n",obj,&obj);
и вы получите что-то вроде:
10 7 -- 0x804a01c
, который имеет правильный адрес:
Вот изображение, чтобы помочь:
What you push What printf uses
+------------+
/ | 10 | %d
obj < +------------+
\ | 7 | %p
+------------+
&obj | 0x80001234 | not-used
+------------+
Я видел подобные проблемы, когда люди передают long
в printf
с целочисленным форматом %d
. %d
использует только первую часть long
, а вторая часть - все остальные аргументы. Подробнее см. здесь .
Вот почему у gcc есть те милые маленькие согревающие сообщения, которые появляются при несовпадении типов со спецификаторами в семействе функций printf
:
qq.c: In function ‘main’:
qq.c:14: warning: incompatible implicit declaration of built-in function ‘printf’
qq.c:14: warning: format ‘%d’ expects type ‘int’, but argument 2
has type ‘struct temp’