如何避免因未定义行为而写出厌氧代码

灌水区

Melo.VVちゃん @ 2024-07-06 15:39:53

rt,bdfs 无果。


by Melo.VVちゃん @ 2024-07-06 15:41:16

因为代码厌氧卡了 1 天,最后把 O_2 关掉就 A 了


by yukimianyan @ 2024-07-06 15:46:07

重学 C++。


by Melo.VVちゃん @ 2024-07-06 15:47:48

@yukimianyan 其实我完全可以不这么做的


by LA1cIFf0yxOR @ 2024-07-06 15:48:20

@shin_chan_jiang 加编译选项 -fsanitize=undefined


by LA1cIFf0yxOR @ 2024-07-06 15:53:00

@shin_chan_jiang 注意不要过度依赖这个,这个东西会让你的代码变慢,之前有个卡常题我本地跑了 9s,去掉这个就只要 4s 了


by Melo.VVちゃん @ 2024-07-06 15:56:48

@a1co0av5ce5az1cz0ap_ 感谢


by Famishin @ 2024-07-06 18:12:28

@shin_chan_jiang -Wall 报警告应该也能避免吧(?)


by Glacyend @ 2024-07-06 19:09:39

@yukimianyan @shin_chan_jiang @a1co0av5ce5az1cz0ap_ @DioxygenDifluoride

UB(未定义行为)是指代码中不包含在标准中的行为,分为“不同编译器有不同实现方式”和“默认情况”两种,而 O2 出现负优化的通常是后者。通常来说,使用 -Wall 启用所有警告即可大幅度避免未定义行为。

这个警告是所有 OIER 都容易忽略的:

std::vector<int> numbers;
// ...
for (int i = 0; i < numbers.size(); i++) {
    // ...
}
// Warning: i 是 int 类型但是 numbers.size() 返回 std::size_t(64 为系统上为 unsigned long long 的别名),整型大小不相同且是有符号与无符号的比较,容易产生不可预测的溢出。
// 正确改法:
using std::operator""zu;
// C++11 引入了字面量重载,C++23 提供了 std::size_t 的字面量
// 改法 1
for (auto /* or std::size_t */ i = 0zu; i < numbers.size(); i++) {
    // ...
}
// 改法 2
for (std::size_t i = 0; i < numbers.size(); i++) {
    // ...
}

|