考虑以下基本示例:
#include <stdio.h>
int main(void)
{
printf("Hi there!\n");
}
它是否在C89中调用未定义的行为?我试着从这个问题那里得到一些感觉,但是大多数被否决的答案都声称它是由实现定义的,而且这里肯定没有UB (这里有Keith的评论,这看起来很矛盾)。
规范在第3.16节中规定了定义和约定
如果出现在约束之外的“应”或“不”要求被违反。行为是未定义的。在本国际标准中,未定义的行为以“未定义的行为”或对行为的任何明确定义的省略来表示。这三种语言在强调程度上没有区别:它们都描述“未定义的行为”。
第5.1.2.2.3节终止方案
对
main
函数的初始调用的返回相当于调用exit
函数,main
函数返回的值作为其参数。如果main
函数执行未指定值的返回,则未定义返回到主机环境的终止状态。
我的理解是,后一个子子句不包括缺少返回的情况,因为return
语句在not调用中没有调用,因此前一个子子句适用。
然而,进一步的阅读表明了一些不同的东西,第6.6.6.4节,return
语句
如果没有表达式的
return
语句被执行,并且调用方使用函数调用的值,则行为是未定义的。到达终止函数的}
return
的等同于在没有表达式的情况下执行return
语句。
好的,现在5.1.2.2.3
分句适用于:
如果
main
函数执行不指定值的返回。返回到主机环境的终止状态未定义。
术语“终止状态是未定义的”似乎不是UB,也不是任何特定的行为,但更像是超出了C标准的范围,更像是:“让主机环境担忧,我们在这里洗手”。这是正确的整数吗?
发布于 2015-01-28 15:03:57
几年前,我实际上是从这件事中发现了一些问题。如果您有一些有返回的代码路径,而另一些没有返回,则会变得更加有趣。
正如@aruisdante在评论中推测的那样,所展示的行为确实是“未定义的”,但唯一未定义的部分是返回的值(它不像其他许多可能导致程序崩溃的“未定义”情况一样)。
现在,这实际上是一种安全风险,因为返回的“未定义”值通常是CPU寄存器中通常用于返回值(或某些实现中的堆栈)中发生的任何情况,理论上可以用来泄漏敏感数据。
发布于 2015-01-30 18:23:54
我相信标准委员会的意图是这个终止状态值是没有具体说明的。
根据N739草案:
并将第5.1.2.2.3款最后一句改为: 如果/main/函数执行不指定值的返回,则返回到主机环境的终止状态是未定义的。 至: 如果/main/函数执行未指定值的返回,则返回到主机环境的终止状态为未指定的。 未确定价值的概念在其他地方是谨慎避免的。
您还可以在进一步的标准中发现,术语已被更改,因此使用了术语“未指定”。
我要说的是,这绝对不是有意的行为本身,但它仍然是不可能决定它是未具体的行为,或如我所说,根本没有行为。其他摘录,说明后一节--这是第1节范围
本国际标准未具体规定:
我认为这也意味着该国际标准没有指定主机环境如何处理程序的终止状态。
https://stackoverflow.com/questions/28203506
复制