Se pueden comparar dos objetos diferentes con una duración de almacenamiento automática igual en comparación de direcciones?
n particular, está permitido que las direcciones de dos variables automáticas en diferentes funciones se comparen de la siguiente manera:
sink.c
#include <stdio.h>
#include <stdlib.h>
void sink(void *l, void *r) {
puts(l == r ? "equal" : "not equal");
exit(0);
}
C Principa
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);
}
Esperaría que esto imprimanot equal
comof1
yf2
son objetos distintos. Con gcc obtengonot equal
, pero con mi versión local de clang 3.81, imprimeequal
, cuando se compila comoclang -O1 sink.c main.c
2.
Disassemblingmake
ymain
...
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
... vemos esomake
nunca parece crear elFoo f2
objeto en absoluto, solo llama asink
con el @ existenrdi
yrsi
(ell
yr
parámetros, respectivamente). Estos son aprobados pormain
y son lo mismo: el primero,rdi
, es el puntero oculto a la ubicación para poner el valor de retorno, y el segundo es&f1
, por lo que esperamos que sean lo mismo.
1 Revisé las versiones hasta 7.0 y el comportamiento es más o menos el mismo.
2 Sucede para-O1
, -O2
y-O3
, pero no-O0
que imprimenot equal
en su lugar.