viz*_*pft 3 c++ optimization memory-leaks machine-code
当我实现一个程序时,我发现我的程序在 g++ 或 clang++ 中从 切换-g
到时表现不同-O2
。
简化的代码是:
#include <cstdint>
#include <iostream>
class A {
public:
explicit A(const int64_t &zero_);
const int64_t& zero;
};
A::A(const int64_t &zero_):
zero(zero_) {
std::cout << "zero=" << zero << std::endl;
}
int main() {
A st(0);
size_t p;
std::cin >> p;
std::cout << "zero=" << st.zero << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
假设标准输入为 1,并且异常输出(在最后一行中)为零 = 0,因为该变量zero
是一个常量引用。
使用 编译时g++ -g -o b.o b.cc
,程序运行正常。
但是,当用 编译时g++ -O2 -o b.o b.cc
,输出是zero=1
实际上,它输出 的值p
。
这是错误还是预期行为?
在 Debian10 amd64 上测试
Pau*_*ers 10
A::zero
是一个悬空参考,因此是 UB。
构造时st
,会创建一个临时对象来传递参数。这个临时在语句的末尾超出了范围,但st.zero
仍在引用它。因此,当您尝试使用它时,会发生一些神秘的事情。
-g 和 -O2 之间的差异是巧合。使用 UB,可以根据具体情况发生不同的事情。