在 class 中使用对文字的 const 引用时 C++ O2 内存泄漏
C++ O2 Memory leak when using const reference to literal in class
当我实现一个程序时,我发现我的程序在 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;
}
假设标准输入为 1,例外输出(最后一行)为零=0,因为变量 zero
是一个常量引用。
使用 g++ -g -o b.o b.cc
编译时,程序运行正常。
然而,当用g++ -O2 -o b.o b.cc
编译时,输出是zero=1
其实就是输出p
的值。
这是错误还是预期行为?
在 Debian10 amd64 上测试
A::zero
是悬空引用,因此是 UB。
当你构造st
时,会创建一个临时文件来传递参数。这个临时变量在语句末尾超出范围,但 st.zero
仍然引用它。因此,当你尝试使用它时,神秘的事情就会发生。
-g 和-O2 的区别纯属巧合。使用 UB,根据具体情况可能会发生不同的事情。
当我实现一个程序时,我发现我的程序在 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;
}
假设标准输入为 1,例外输出(最后一行)为零=0,因为变量 zero
是一个常量引用。
使用 g++ -g -o b.o b.cc
编译时,程序运行正常。
然而,当用g++ -O2 -o b.o b.cc
编译时,输出是zero=1
其实就是输出p
的值。
这是错误还是预期行为?
在 Debian10 amd64 上测试
A::zero
是悬空引用,因此是 UB。
当你构造st
时,会创建一个临时文件来传递参数。这个临时变量在语句末尾超出范围,但 st.zero
仍然引用它。因此,当你尝试使用它时,神秘的事情就会发生。
-g 和-O2 的区别纯属巧合。使用 UB,根据具体情况可能会发生不同的事情。