@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.c2.

Дизассемблирование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 вместо.

Ответы на вопрос(1)

Ваш ответ на вопрос