Dois objetos diferentes com duração de armazenamento automático podem ser comparados na comparação de endereços?

Em particular, é permitido comparar os endereços de duas variáveis automáticas em funções diferentes da seguinte maneira:

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);
}

Eu esperaria que isso fosse impressonot equal Comof1 ef2 são objetos distintos. Com o gcc eu recebonot equal$7sink.c8$equal, quando compilado comoclang -O1 sink.c main.c2.

Desmontagemmake emain ...

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    

... nós vemos quemake parece nunca criar oFoo f2 objeto, apenas chamasink com o existenterdi ersi (al er parâmetros, respectivamente). Estes são passados pormain e são os mesmos: o primeiro,rdi, é o ponteiro oculto para o local para inserir o valor de retorno e o segundo é&f1, então esperamos que eles sejam iguais.

1 Eu verifiquei versões até 7.0 e o comportamento é aproximadamente o mesmo.

2 Isso acontece para-O1, -O2 e-O3, mas não-O0 que imprimenot equal em vez de.

questionAnswers(1)

yourAnswerToTheQuestion