为什么从 constexpr 引用生成的程序集代码与从 constexpr 指针生成的程序集代码不同?
Why is different assembly code generated from a constexpr reference than a constexpr pointer?
我用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
的代码(。见神电。为什么ir
和ip
不同?我了解到,在汇编代码中引用和指针是相同的。
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;}
因此,必须有一个符号来附加这种用途。
相关文章:
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- 为什么在堆栈和堆上创建变量会产生相同的程序集代码?
- 为什么从 constexpr 引用生成的程序集代码与从 constexpr 指针生成的程序集代码不同?
- 在OpenGL中使用程序集代码渲染视频时出错
- 如何编写与此程序集代码相等的c/c++代码
- 在 C++ 中调用时对内联程序集代码的未定义引用
- 在结构中嵌入函数程序集代码
- 如何使用g++获取C++头文件(.hpp)的程序集代码
- 如何在不创建新进程的情况下运行程序集代码
- 从C++调用程序集代码
- 用于将 C# 运行时代码编译为本机程序集代码(可从C++应用程序调用)中的.dll的方法
- C 样式转换是添加程序集(代码)还是仅供编译器了解情况
- 如何将此内联程序集代码转换为x64程序集
- 简单的程序集代码会产生缓冲区溢出
- 为什么构造函数/析构函数在g++生成的程序集代码中是这样定义的
- 在已编译的可执行文件的.text部分中增加或指定间隙,以手动添加程序集代码
- 如何在C++中内联自修改程序集代码
- gcc-编译x386程序集代码错误
- 在编译内联程序集代码时打开调试器