是否在 C89(又名 ANSI C)中省略 return 语句未定义的行为?
Is omitting return statement undefined behaviour in C89 (aka ANSI C)?
考虑以下基本示例:
#include <stdio.h>
int main(void)
{
printf("Hi there!\n");
}
它是否调用了 C89 中的未定义行为?我试图从 this question 中获得一些意义,但大多数赞成的答案声称它是实现定义的,这里绝对没有 UB(Keith Thompson 的评论,这看起来自相矛盾)。
规范在§3.16 定义和约定:
If a “shall” or “shall not” requirement that appears outside of a
constraint is violated. the behavior is undefined. Undefined behavior
is otherwise indicated in this International Standard by the words
“undefined behavior” or by the omission of any explicit definition of
behavior. There is no difference in emphasis among these three: they
all describe “behavior that is undefined”.
和§5.1.2.2.3 程序终止:
A return from the initial call to the main
function is equivalent to
calling the exit
function with the value returned by the main
function
as its argument. If the main
function executes a return that specifies
no value, the termination status returned to the host environment is
undefined.
我的理解是后面的子条款不包括丢失 return 的情况,因为 return
语句并非从未被调用,因此适用前面的子条款。
然而,进一步阅读表明有所不同,§6.6.6.4 return
声明:
If a return
statement without an expression is executed, and the value
of the function call is used by the caller, the behavior is undefined.
Reaching the }
that terminates a function is equivalent to executing a
return
statement without an expression.
好的,现在 5.1.2.2.3
子条款适用:
If the main
function executes a return that specifies
no value. the termination status returned to the host environment is
undefined.
术语 "termination status is undefined" 似乎不是 UB,也不是 任何特定行为 ,但更像是它超出了 C 标准的范围,更像是:"let the host environment to be worry about, we wash our hands from here"。解读正确吗?
几年前,我实际上调试过由此引起的问题。如果您有一些代码路径带有 returns 而另一些没有。
正如@aruisdante 在评论中推测的那样,表现出的行为确实是 'undefined',但唯一未定义的部分是值 returned(它不像许多其他 'undefined' 情况这可能会使程序崩溃)。
如今,这实际上构成了安全风险,因为 'undefined' 值 returned 通常是通常用于 return 的 CPU 寄存器中的任何值值(或在某些实现中位于堆栈上),理论上可用于泄漏敏感数据。
我相信标准委员会的意图是未指定此终止状态值。
根据N739草稿:
and change the last sentence of subclause 5.1.2.2.3 from:
If the /main/ function executes a return that specifies no value,
the termination status returned to the host environment is undefined.
to:
If the /main/ function executes a return that specifies no value, | the termination status returned to the host environment is
unspecified.
[The concept of undefined value is carefully avoided elsewhere.]
您可能还会在其他标准中发现,术语已更改,因此使用术语“未指定”。
我会说它本身绝对不是有意成为未定义的行为,但仍然无法确定它是未指定的行为还是我所说的根本没有行为。其他摘录,表明后者是 §1 Scope:
This International Standard does not specify:
- the mechanism by which C programs are invoked for use by a data-processing system;
我希望这也意味着该国际标准没有指定宿主环境如何处理程序的终止状态。
考虑以下基本示例:
#include <stdio.h>
int main(void)
{
printf("Hi there!\n");
}
它是否调用了 C89 中的未定义行为?我试图从 this question 中获得一些意义,但大多数赞成的答案声称它是实现定义的,这里绝对没有 UB(Keith Thompson 的评论,这看起来自相矛盾)。
规范在§3.16 定义和约定:
If a “shall” or “shall not” requirement that appears outside of a constraint is violated. the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words “undefined behavior” or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three: they all describe “behavior that is undefined”.
和§5.1.2.2.3 程序终止:
A return from the initial call to the
main
function is equivalent to calling theexit
function with the value returned by themain
function as its argument. If themain
function executes a return that specifies no value, the termination status returned to the host environment is undefined.
我的理解是后面的子条款不包括丢失 return 的情况,因为 return
语句并非从未被调用,因此适用前面的子条款。
然而,进一步阅读表明有所不同,§6.6.6.4 return
声明:
If a
return
statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined. Reaching the}
that terminates a function is equivalent to executing areturn
statement without an expression.
好的,现在 5.1.2.2.3
子条款适用:
If the
main
function executes a return that specifies no value. the termination status returned to the host environment is undefined.
术语 "termination status is undefined" 似乎不是 UB,也不是 任何特定行为 ,但更像是它超出了 C 标准的范围,更像是:"let the host environment to be worry about, we wash our hands from here"。解读正确吗?
几年前,我实际上调试过由此引起的问题。如果您有一些代码路径带有 returns 而另一些没有。
正如@aruisdante 在评论中推测的那样,表现出的行为确实是 'undefined',但唯一未定义的部分是值 returned(它不像许多其他 'undefined' 情况这可能会使程序崩溃)。
如今,这实际上构成了安全风险,因为 'undefined' 值 returned 通常是通常用于 return 的 CPU 寄存器中的任何值值(或在某些实现中位于堆栈上),理论上可用于泄漏敏感数据。
我相信标准委员会的意图是未指定此终止状态值。
根据N739草稿:
and change the last sentence of subclause 5.1.2.2.3 from:
If the /main/ function executes a return that specifies no value, the termination status returned to the host environment is undefined.
to:
If the /main/ function executes a return that specifies no value, | the termination status returned to the host environment is unspecified.
[The concept of undefined value is carefully avoided elsewhere.]
您可能还会在其他标准中发现,术语已更改,因此使用术语“未指定”。
我会说它本身绝对不是有意成为未定义的行为,但仍然无法确定它是未指定的行为还是我所说的根本没有行为。其他摘录,表明后者是 §1 Scope:
This International Standard does not specify:
- the mechanism by which C programs are invoked for use by a data-processing system;
我希望这也意味着该国际标准没有指定宿主环境如何处理程序的终止状态。