相关疑难解决方法(0)

假定具有未定义行为的分支是否无法访问并优化为死代码?

请考虑以下声明:

*((char*)NULL) = 0; //undefined behavior
Run Code Online (Sandbox Code Playgroud)

它明确地调用未定义的行为.在给定的程序中是否存在这样的语句意味着整个程序是未定义的,或者一旦控制流命中这个语句,该行为只会变得不确定?

如果用户从未输入数字,3是否可以明确定义以下程序?

while (true) {
 int num = ReadNumberFromConsole();
 if (num == 3)
  *((char*)NULL) = 0; //undefined behavior
}
Run Code Online (Sandbox Code Playgroud)

或者,无论用户输入什么,它都是完全未定义的行为?

此外,编译器是否可以假定在运行时永远不会执行未定义的行为?这样可以及时推理:

int num = ReadNumberFromConsole();

if (num == 3) {
 PrintToConsole(num);
 *((char*)NULL) = 0; //undefined behavior
}
Run Code Online (Sandbox Code Playgroud)

在这里,编译器可以推断,以防num == 3我们总是调用未定义的行为.因此,这种情况必须是不可能的,并且不需要打印该号码.整个if声明可以优化.根据标准,是否允许这种向后推理?

c++ dead-code undefined-behavior language-lawyer unreachable-code

88
推荐指数
3
解决办法
3338
查看次数

在循环中的什么时候整数溢出变成未定义的行为?

这是一个例子来说明我的问题,其中涉及一些我不能在这里发布的更复杂的代码.

#include <stdio.h>
int main()
{
    int a = 0;
    for (int i = 0; i < 3; i++)
    {
        printf("Hello\n");
        a = a + 1000000000;
    }
}
Run Code Online (Sandbox Code Playgroud)

这个程序在我的平台上包含未定义的行为,因为它a会在第3个循环中溢出.

这是否会使整个程序具有未定义的行为,或者仅在溢出实际发生之后?编译器是否可能a 会解决溢出问题,因此它可以声明整个循环未定义,并且不会打扰运行printfs,即使它们都在溢出之前发生?

(标记为C和C++,即使它们不同,因为如果它们不同,我会对这两种语言的答案感兴趣.)

c c++ integer-overflow undefined-behavior

85
推荐指数
7
解决办法
1万
查看次数

为什么常量表达式会排除未定义的行为?

我正在研究核心常量表达式*中允许的内容,这在C++标准草案的5.19 常量表达式2段中有所描述:

条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2),但是未评估的逻辑AND(5.14),逻辑OR(5.15)和条件(5.16)操作的子表达式不考虑[注意:重载的运算符调用函数.-end note]:

并列出随后的子弹中的排除项并包括(强调我的):

- 具有未定义行为的操作 [注意:包括,例如,有符号整数溢出(第5条),某些指针算术(5.7),除零(5.6)或某些移位操作(5.8) - 结束注释];

?为什么常量表达式需要此子句来涵盖未定义的行为常量表达式是否有一些特殊的东西需要未定义的行为才能在排除中进行特殊划分?

拥有这个条款是否给了我们没有它的任何优势或工具?

作为参考,这看起来像广义常量表达式提案的最新修订版.

c++ sfinae undefined-behavior constexpr c++11

46
推荐指数
3
解决办法
2752
查看次数