Syl*_*ert 0 c undefined-behavior
该博客声称:
- 未定义的行为仅在高优化级别(例如 -O2 或 -O3)下“发生”。
- 如果我使用 -O0 之类的标志关闭优化,那么就没有 UB。
都是假的。我想知道是否有任何现实世界的展示可以证明这一点。
例如,n << 1当 时触发 UB n<0。对于以下函数:
void foo(int n) {
int t = n<<1;
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
编译器可以谨慎地编译它:
void foo(int n) {
int t = n>=0 ? (n*2) : error("lshift negative int");
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
或通常:
void foo(int n) {
int t = n*2;
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
或者积极优化它:
void foo(int n) {
// unused
// int t = n<<1;
// always true, otherwise UB
// if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
是否有像 gcc/clang 这样的现代流行编译器以最后一种方式运行,其中某些 UB 不仅会在该语句本地导致意外行为,而且还可能被故意利用(不考虑缓冲区溢出攻击等)并污染控制流在全球范围内,即使-O0指定了?
简而言之,所有 UB实际上都是在某种程度上实现定义的吗-O0?
==编辑==
问题不在于这些主张在理论上是否错误或无意义(因为它们确实是)。而是是否有现实世界的展示。正如 @nate-eldredge 在评论中重新表述的那样:
给定一些形式上为 UB 的代码,现实生活中的非优化编译器会产生特别令人惊讶的结果(以上述方式),即使对于知识渊博的程序员来说也是如此?
Run Code Online (Sandbox Code Playgroud)Undefined behavior only "happens" at high optimization levels like -O2 or -O3. If I turn off optimizations with a flag like -O0, then there's no UB.
这是错误的,原因之一。C 语言中未定义的内容在 C 标准中已定义。未定义行为意味着从C语言的角度来看,我们不知道程序将如何表现。UB 不必以任何特定方式表达自己 - 但它仍然是 UB。
这些说法源于不了解 UB 是什么。UB 不会“发生”。它们处于C语言级别。即使程序“运行良好”,它仍然是 UB。由于行为未定义,如果您更改编译器、编译器版本、编译器选项或在其他操作系统或硬件上运行,它可能会停止工作。
| 归档时间: |
|
| 查看次数: |
222 次 |
| 最近记录: |