我找不到控制C语言的命名返回值优化的标志。对于C++,它似乎是-FNO-ELID构造函数。
实现它的源代码是here但由于它是一个中间端,因此即使在注释中也不会破坏前端信息。The manual section也没有帮助。但是,反汇编显示,当它在O0上关闭并在O1上启用时,它必须是以下之一:

      -fauto-inc-dec
      -fcprop-registers
      -fdce
      -fdefer-pop
      -fdelayed-branch
      -fdse
      -fguess-branch-probability
      -fif-conversion2
      -fif-conversion
      -finline-small-functions
      -fipa-pure-const
      -fipa-reference
      -fmerge-constants
      -fsplit-wide-types
      -ftree-builtin-call-dce
      -ftree-ccp
      -ftree-ch
      -ftree-copyrename
      -ftree-dce
      -ftree-dominator-opts
      -ftree-dse
      -ftree-fre
      -ftree-sra
      -ftree-ter
      -funit-at-a-time

C代码:
struct p {
    long x;
    long y;
    long z;
};

__attribute__((noinline))
struct p f(void) {
    struct p copy;
    copy.x = 1;
    copy.y = 2;
    copy.z = 3;
    return copy;
}

int main(int argc, char** argv) {
    volatile struct p inst = f();
    return 0;
}

使用O0编译后,我们看到“copy”结构是在堆栈上天真地分配的:
00000000004004b6 <f>:
  4004b6:   55                      push   rbp
  4004b7:   48 89 e5                mov    rbp,rsp
  4004ba:   48 89 7d d8             mov    QWORD PTR [rbp-0x28],rdi
  4004be:   48 c7 45 e0 01 00 00    mov    QWORD PTR [rbp-0x20],0x1
  4004c5:   00
  4004c6:   48 c7 45 e8 02 00 00    mov    QWORD PTR [rbp-0x18],0x2
  4004cd:   00
  4004ce:   48 c7 45 f0 03 00 00    mov    QWORD PTR [rbp-0x10],0x3
  4004d5:   00
  4004d6:   48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  4004da:   48 8b 55 e0             mov    rdx,QWORD PTR [rbp-0x20]
  4004de:   48 89 10                mov    QWORD PTR [rax],rdx
  4004e1:   48 8b 55 e8             mov    rdx,QWORD PTR [rbp-0x18]
  4004e5:   48 89 50 08             mov    QWORD PTR [rax+0x8],rdx
  4004e9:   48 8b 55 f0             mov    rdx,QWORD PTR [rbp-0x10]
  4004ed:   48 89 50 10             mov    QWORD PTR [rax+0x10],rdx
  4004f1:   48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  4004f5:   5d                      pop    rbp
  4004f6:   c3                      ret

用O1编译时未分配,但指针作为隐式参数传递
00000000004004b6 <f>:
  4004b6:   48 89 f8                mov    rax,rdi
  4004b9:   48 c7 07 01 00 00 00    mov    QWORD PTR [rdi],0x1
  4004c0:   48 c7 47 08 02 00 00    mov    QWORD PTR [rdi+0x8],0x2
  4004c7:   00
  4004c8:   48 c7 47 10 03 00 00    mov    QWORD PTR [rdi+0x10],0x3
  4004cf:   00
  4004d0:   c3                      ret

最佳答案

最接近GCC的是-fcprop-registers。C中不存在复制删除,但这是最相似的特性。从手册页:
寄存器分配和寄存器后分配指令
拆分时,我们执行复制传播过程以尝试减少
调度依赖关系,偶尔消除拷贝。
在-O、-O2、-O3、-Os水平下启用。

10-07 20:16