为什么从constexpr引用生成的汇编代码与constexpr指针不同?

问题描述 投票:1回答:1

我用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的代码)。参见godbolt。为什么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
  • With -O2代码是从引用而不是指针生成的。为什么会有这种差异?请参见godbolt
c++ pointers reference code-generation constexpr
1个回答
0
投票

除了指令问题之外,这只是linkageconstexpr隐含const(在变量本身上,而不是其引用对象,如果有的话),从而将internal linkage赋予指针。 (这是一种黑客,允许在C ++ 17的内联变量之前的头文件中使用名称空间范围的命名常量;很遗憾,我们现在必须记住它。)由于没有其他翻译单元可以引用它们,因此无需发出符号;但是,引用可以在其他地方声明和使用:

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

因此,必须有附加此类使用的符号。

© www.soinside.com 2019 - 2024. All rights reserved.