【问题标题】:Why is return 0 optional?为什么 return 0 是可选的?
【发布时间】:2010-11-09 21:08:24
【问题描述】:

为什么,如果我写

int main() 
{ 
    //... 
}

我不需要在main 函数的末尾写return 0; 吗?编译器会帮我做吗?

我使用 GCC/C99。

【问题讨论】:

  • 您通常希望记住您的退货声明。如果您只为自己编写小程序,您可能不会遇到问题。但是,如果您编写大型程序或组合许多不同的程序,最好让接口按预期运行。当程序返回 0 时,表示成功完成,其他值表示错误。依赖编译器/平台特定的函数来保持代码工作可能会导致问题。

标签: c


【解决方案1】:

C99 和 C++ 的特殊情况 main 函数返回 0 如果控制在没有显式返回的情况下到达末尾。此适用于main 函数。

对于main 特殊情况,C99 规范的相关位是 5.1.2.2.3

5.1.2.2.3 程序终止

如果主函数的返回类型 是与 int 兼容的类型,a 从初始调用返回 main函数相当于调用 具有值的退出函数
由主函数返回为其 争论; 到达} 终止主函数返回 值为 0。

6.9.1/12

如果终止函数的} 是 达到,以及函数的值 call 被调用者使用, 行为未定义。

你可以用 gcc 测试一下:

int foo ( void ) { }
int main( void ) { }

C89 模式(两个函数都有错误):

sandiego:$ gcc src/no_return.c -std=c89 -Wall 
src/no_return.c: In function ‘main’:
src/no_return.c:2: warning: control reaches end of non-void function
src/no_return.c: In function ‘foo’:
src/no_return.c:1: warning: control reaches end of non-void function

C99 模式(main 是一个特例):

sandiego:$ gcc src/no_return.c -std=c99 -Wall
src/no_return.c: In function ‘foo’:
src/no_return.c:1: warning: control reaches end of non-void function

【讨论】:

    【解决方案2】:

    如果函数末尾没有明确的 return 语句,则最新的 C(目前是 C99,有一些修改)默认从 main 返回 0,并且控制从函数的末尾流出(参见 5.1 .2.2.3 在C99 TC3)。这是因为大多数情况下,无论如何都会写出这样一种形式的回报。

    在 C89 中,您需要在那里返回一些东西——它没有这样的隐式返回。但编译器绝不需要诊断此类错误(请参阅C89 draft 中的 3.6.6.4 和C99 TC3 中的 6.9.1/12)。

    【讨论】:

    • 在 C 标准中它声明 如果 main 函数末尾没有明确的 return 语句,则函数 main 默认返回 0 它只声明了这个 reaching终止主函数的 } 返回值 0。如果没有显式返回语句的条件不会出现在那里
    【解决方案3】:

    是的。 C 中的main 是一个非常特殊的函数,它有一些额外的规则。请参阅 C99 标准中有关其终止的段落。从本质上讲,如果你退出函数而不返回值,这相当于你给了一个返回值0。这对于main 来说是特殊的,在调用函数期望返回值的其他函数中这样做可能(并且将会)使您的程序崩溃。

    如果 main 的返回类型 函数是一种兼容的类型 int,从初始调用返回 主要功能相当于 调用退出函数 主函数返回的值为 它的论点;到达 } 终止主函数返回一个 值为 0。如果返回类型不是 与 int 兼容,终止 状态返回给主机 环境未指定。

    【讨论】:

      【解决方案4】:

      基本上,是的。函数不需要返回任何内容,即使它们声明了void 以外的返回类型。返回的值将是未定义的。

      请注意,C99 要求声明非void 返回类型的函数始终通过返回语句终止。因此,如果您使用编译器的 C99 模式进行编译,此代码将导致编译时错误。

      【讨论】:

      • 您能否链接到 C99 标准的相应部分来确认这一点?这似乎与 Johannes Schaub - litb 的回答相矛盾。
      • 我从这里阅读,声称它是 C99 规范的一部分。我自己并没有真正检查规格。 publib.boulder.ibm.com/infocenter/comphelp/v8v101/…
      • 表示“在为严格符合 C99 的编译下,定义为返回类型的函数必须包含一个包含要返回的值的表达式。”一般情况下是这样,但是讨论的函数发生在 main 上,这是一个特例。
      • @Pete 我确实认为该页面是错误的。 C99 似乎没有这样的要求:它只声明在非 void 函数中有一个没有值的 return 语句需要诊断。然而,它并没有说明从值返回函数的末尾流出需要诊断,因为 C99 似乎不再具有“返回”的规则;不存在时会自动插入,C89 确实有。
      • @Johannes C99 § 6.9.1#12 说(正如您在回答中所说),控制到达函数的末尾是未定义的行为,该函数将值返回给调用者。页面有点错误,int foo(void) { while (true); } 按照规范没有 UB,但不满足有值返回的要求。从 main 返回 0 在 C99 § 5.1.2.2.3
      猜你喜欢
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多