为什么从 constexpr 引用生成的程序集代码与从 constexpr 指针生成的程序集代码不同?

Why is different assembly code generated from a constexpr reference than a constexpr pointer?

本文关键字:程序集 代码 constexpr 为什么 引用 指针      更新时间:2023-10-16

我用MSVC/O2和clang编译了以下程序:

int            i;
constexpr int& ir = i;
constexpr int* ip = &i;

int main()
{
ir  = 1;
*ip = 2;
}
MSVC /O2                           clang
===========================        =============================================
int i DD 01H DUP (?) ; i           i:
_DATA SEGMENT                              .long   0                       # 0x0
int & ir DQ FLAT:int i ; ir
_DATA ENDS                         ir:
.quad   i
  • 两个编译器都从ir生成汇编代码,但不从ip生成汇编代码(上面省略了main的代码(。见神电。为什么irip不同?我了解到,在汇编代码中引用和指针是相同的。

GCC做了一件更奇怪的事情。我用 gcc-O0-O2编译了以下程序:

int            i;
constexpr int& ir1   = i;
constexpr int* ir1p1 = &i;
constexpr int& ir2   = i;
constexpr int* ir2p1 = &i;
constexpr int* ir2p2 = &i;
constexpr int& ir3   = i;
constexpr int* ir3p1 = &i;
constexpr int* ir3p2 = &i;
constexpr int* ir3p3 = &i;
gcc -O0            gcc -O2
=========          ==================
i:                 ir3:
.zero 4                   .quad   i
ir1:               ir2:
.quad i                   .quad   i
.quad i          ir1:
ir2:                        .quad   i
.quad i          i:
.quad i                   .zero   4
.quad i
ir3:
.quad i
.quad i
.quad i
.quad i
  • 有了-O0为什么参考变量下有几个.quad i
  • 使用-O2代码是从引用生成的,而不是从指针生成的。为什么会有这种差异?见神电。

除了指令问题,这只是链接constexpr意味着const(在变量本身上,而不是它的引用,如果有的话(,从而给你的指针提供内部链接。 (这是一个允许在 C++17 的内联变量之前的头文件中使用命名空间范围命名常量的黑客;不幸的是,我们现在必须记住它。 由于没有其他翻译单元可以引用它们,因此无需为它们发出符号;但是,可以在其他地方声明和使用引用:

extern int &ir;
void count() {++ir;}

因此,必须有一个符号来附加这种用途。