了解未定义行为的范围
Understanding the scope of undefined behavior
C++标准以何种方式(如果有的话)限制了未定义行为的影响? 例如,在下面的代码中,从第一个if
开始检查undefined
控制流是否受限于遵循当时路径或 else 路径? 是否允许跳过两条路径?执行两条路径(可能并行执行)?狂野地跳到第二if
中间?
void f(int undefined) {
bool startNuclearWar = true;
if (undefined > 0) {
printf("True pathn");
startNuclearWar = false;
} else {
printf("False pathn");
startNuclearWar = false;
}
if (startNuclearWar) {
lauchMissles();
}
}
该标准对 UB 没有限制。当你做任何调用UB的事情时,标准并不能保证会发生什么。
虽然在许多情况下,能够"划分"未定义的行为是有用的,并且虽然这样做在许多平台上会很便宜,但编写标准的人并没有表现出任何显着的兴趣。 C11标准提供了关于"可分析性"的附录L,但它没有描述任何有意义的东西,如果定义__STDC_ANALYZABLE__
,实现必须保证。
例如,整数溢出是有界未定义行为的事实,如果没有一种干净的方法来确保代码如下,那么它的用处将是有限的:
int index = computeSomething();
if (index < 0 || index >= ARRAYSIZE) FatalError();
myArray[index]++;
将在比较和数组查找中对index
使用相同的值。
许多实现可以廉价地提供超出标准要求的许多有用保证,特别是在应用领域,当给定无效输入时,程序异常终止是可以接受的,但不允许恶意构造的输入控制机器。 不幸的是,该标准未能提供必要的钩子来有效地利用这一点(例如,提供一个内在的,该内在函数将采用一个可能不确定的值,并产生一个最坏的情况是未指定的值)。 在执行比较之前,将这样的内在应用于上述代码中index
的值将确保即使在computeSomething
中发生溢出,代码也会保证在数组中增加一个值,或者注意到index
无效。 由于这两个操作都不会导致严重未定义行为,因此执行将保持在轨道上。
C++标准以何种方式(如果有的话)限制了未定义行为的影响?
都不是。 未定义的行为本质上是未定义的,因此绝对可能发生任何事情。 一旦发生了未定义的事情,程序的状态从那时起就未知了。
话虽如此,您显示的代码中没有未定义的行为。 代码中的所有内容都有定义的行为。
例如,在下面的代码中,从第一个
if
开始检查undefined
控制流是否受限于遵循当时路径或 else 路径?
是的。
是否允许跳过两条路径?
不。
执行两条路径(可能并行执行)?
不。
疯狂地跳到秒中间如果?
不。
- 编译C++时未定义的引用
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- c++11评估顺序(未定义的行为)
- 使用mysql c++连接器的未定义引用
- 是否未定义将对函数范围变量的引用作为值返回
- C++未定义的行为unordered_map为基于范围的 for 循环中的右值
- QT版本检查和Qoverload未在范围中定义
- 正在访问超出范围的静态未定义行为
- 尝试和捕获中的对象声明未在范围内定义
- 未定义范围 c++ 需要 int inout
- 从堆栈地址形成指针范围是未定义的行为吗
- 为什么在未命名的命名空间中声明变量后无法在全局范围内定义变量?
- 'memcpy'未在此范围内定义