@RbMm мы тоже не удивлены, но это все равно неправильно.
тности, разрешено ли сравнивать адреса двух автоматических переменных в разных функциях следующим образом:
sink.c
#include <stdio.h>
#include <stdlib.h>
void sink(void *l, void *r) {
puts(l == r ? "equal" : "not equal");
exit(0);
}
main.c
typedef struct { char x[32]; } Foo;
void sink(void *l, void *r);
Foo make(void *p) {
Foo f2;
sink(&f2, p);
return f2;
}
int main() {
Foo f1 = make(&f1);
}
Я ожидал бы это напечататьnot equal
какf1
а такжеf2
являются различными объектами. С gcc получаюnot equal
$7sink.c8$equal
при компиляции какclang -O1 sink.c main.c
2.
Дизассемблированиеmake
а такжеmain
...
0000000000400570 <make>:
400570: 53 push rbx
400571: 48 89 fb mov rbx,rdi
400574: e8 d7 ff ff ff call 400550 <sink>
400579: 48 89 d8 mov rax,rbx
40057c: 5b pop rbx
40057d: c3 ret
40057e: 66 90 xchg ax,ax
0000000000400580 <main>:
400580: 48 83 ec 28 sub rsp,0x28
400584: 48 8d 7c 24 08 lea rdi,[rsp+0x8]
400589: 48 89 fe mov rsi,rdi
40058c: e8 df ff ff ff call 400570 <make>
400591: 31 c0 xor eax,eax
400593: 48 83 c4 28 add rsp,0x28
400597: c3 ret
... Мы видим, чтоmake
никогда не создаетсяFoo f2
объект вообще, это просто вызываетsink
с существующимrdi
а такжеrsi
(l
а такжеr
параметры соответственно). Они проходят мимоmain
и одинаковы: первое,rdi
, это скрытый указатель на место, чтобы положить возвращаемое значение, а второй&f1
поэтому мы ожидаем, что они будут одинаковыми.
1 Я проверил версии до 7.0, и поведение примерно такое же.
2 Это происходит для-O1
, -O2
а также-O3
, но нет-O0
какие отпечаткиnot equal
вместо.