如果程序的一部分表现出未定义的行为,它会影响程序的其余部分吗?

时间:2018-02-05 13:30:41

标签: c++ c undefined-behavior

假设程序员忘记初始化他的一个自动变量,并且他使用了它的值,从而调用未定义的行为。

...
int i = 0, j;
...
printf("value of 'j': %d\n", j);
...
...
char buf[256];
fputs("Enter query:", stdout);
fgets(buf, sizeof(buf), stdin);
... //process input
... perform other tasks

程序员注意到屏幕上出现了乱码,并意识到他的程序是错误的,但它并没有崩溃,反而继续。

假设在此之后,程序提示用户输入并期望处理它,显示结果并执行所有独立于未初始化变量的其他任务,鼓励程序员停止使用该程序,修复错误,重新编译,然后运行?该计划的其余部分会不一致吗?

4 个答案:

答案 0 :(得分:16)

一旦达到具有未定义行为的语句,则整个程序的行为未定义。

矛盾的是,之前运行的语句的行为也是未定义的。

答案 1 :(得分:2)

未定义的行为仅仅是编程语言缺乏保证。但当然可能有其他事情决定程序行为,甚至是确定性的方式,例如记录的编译器扩展或操作系统和CPU行为。

因此,您无法从编程语言的角度来解释未定义的行为。该语言将简单地说所有赌注都已关闭,并且不保证该计划的任何行为。

考虑到特定的系统,您可以推断会发生什么。如果这是一件有意义的事情,那就是另一个故事。

在您的具体示例中,典型的系统可能确实只打印一些垃圾,并且程序的其余部分不太可能受到影响。但是UB的情况并非总是如此。

答案 2 :(得分:1)

一旦有了UB,那么就没有什么好处。标准说的。

n1570-3.4.3(P2):

  

可能的未定义行为包括完全忽略具有不可预测结果的情况,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式执行,终止翻译或执行(发布诊断信息)。

此行为适用于整个程序。

答案 3 :(得分:0)

标准假定程序在一台抽象机器上运行"在标准没有要求的任何情况下,可能以最无理取闹的方式随意行事,包括时间旅行。在C标准没有要求的许多情况下,许多真实世界的实现都是针对真实机器的行为定义和记录的。不幸的是,一些编译器编写者很清楚他们的编译器是否会以符合顺序执行程序的所有步骤的方式行事,以及何时它将会或者不会暴露环境的特征行为标准允许但不要求它这样做。

如果编译器指定它如何存储类型int的自动对象,并且这些类型没有陷阱表示,那么这样的规范也可能意味着如果实现的生成代码是始终符合该规范。问题在于许多实现定义了它们如何存储各种对象,但并未指出它们是否以这种方式一致地存储它们,或者仅在标准需要它的情况下存储它们。