【问题标题】:What if I omit the return type of main function in C?如果我在 C 中省略了 main 函数的返回类型怎么办?
【发布时间】:2012-12-05 18:50:38
【问题描述】:

在任何人可能将其标记为相关问题的重复之前。我强调我确实已经阅读了所有这些问题。但我仍然有一些审问(是的,一些小迂腐:))

对于 C

一些结论:

1. In C89(C90), this is _undefined_ .
2. In C99(or C11), a type of int is madatory; control flow reached the closing } 
   will return a value of 0. 

我的审讯来了。

  1. c89,我没有找到关于undefined,但unspecified

    详情:C89中的相关部分为5.1.2.2.1程序启动5.1.2.2.3程序终止注意:两者都在5.1.2.2 托管环境部分,我们后面的讨论仅限于此)

    引用: -- 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.10 If the } that terminates the main function is reached, the termination status returned to the host environment is unspecified.

    请注意那部分:如果 } 终止 ... ,它清楚地表明 如果我们省略返回类型 - 因此 } 将在 -
    终止状态是未指定

    根据undefinedunspecified标准的定义, 我应该说它给出了 unspecified value 因为无论它返回什么都是 合法的 int 值,但 后果未定义-我们无法预测什么值 会导致什么灾难性的后果?

  2. 在 c99 中,int 类型是强制性的,但 gcc --std=c99 给出的测试没有 int 类型(实际上没有返回类型)只给出 waring:return type of 'main' is not 'int' , 但不是错误 ?

    详解:相关部分同c89。

    引用: -- 5.1.2.2.1 程序启动 --

    It shall be defined with a return type of int and ...

    和 -- 4. 一致性 --

    1. In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a prohibition.

    所以 shall 在本标准中应该被解释为 ma​​datory,为什么 gcc 和 swith --std=c99 违反了这一点?

【问题讨论】:

  • 向 gcc 维护者报告错误。
  • 使用 -pedantic-errors 在 GCC 中产生 ISO 违规错误
  • gcc -std=c99 只是一个松散的近似值,它仍然吞噬了大部分已删除的 c89 内容和扩展。但是,它提供了诊断,并且不需要更多。如果你想要一个很好的标准近似值,也可以使用-pedantic-errors
  • 是的,返回类型是强制性的,我相当旧的 GCC (4.4.5) 版本会使用 -std=c99 或更高版本警告它。
  • 未指定是未定义的Synonym

标签: c


【解决方案1】:

C89/90 仍然有隐含的 int 规则,所以main() 等价于int main()。通过省略返回类型,您已将返回类型隐式定义为int。有些人可能会认为这很草率,但它是严格符合的(即,不涉及定义的实现、未定义或未指定的行为)。

对于 C99,已删除隐式 int 规则,因此未定义 main()然而,编译器仅在遇到违反ShallShall not 子句时才需要“发出诊断”——发出诊断后仍然可以继续编译。究竟什么构成诊断是实现定义的。因此,gcc 在这方面符合要求的只是说明它发出的警告将被视为诊断的文档。

编辑:C89/90 标准中的“隐式int”实际上并不是一个地方的单一规则——它分布在几个地方。主要的是§6.5.2.1,它说:

-- intsignedsigned int,或者没有类型说明符

这是列表的一部分,列表的每一行上的所有项目都被认为是等效的,所以这就是说(除非另有禁止)缺少类型说明符等同于指定(签名)int

对于函数参数,有一个单独的规范(第 6.7.1 节):“任何未声明的参数的类型为 int。”

【讨论】:

  • [C89/90 仍然有隐含的 int 规则] 请给我标准中的引文好吗?
  • @larmbr:查看编辑后的答案 [我讨厌打印在纸上的标准]。
【解决方案2】:

即使在违反约束的情况下,C 编译器唯一必须发出的就是“诊断”。然后允许它继续并生成一个可执行程序。

【讨论】:

  • 谢谢。我使用 -pedantic-erros 开关然后它会报错
【解决方案3】:

请注意那部分:如果终止的 } ... ,它清楚地表明如果我们省略返回类型

不,它没有。它说明当您从 main() 末尾省略 return exitStatus; 时会发生什么。

根据** undefined ** 和 unspecified 标准的定义,我应该说它给出了 unspecified 值,因为它返回的都是合法的 int 值,但结果是 undefined ——我们无法预测会导致什么值造成什么灾难性后果。

没有。这意味着你不知道你的程序的返回状态码是什么。但是,该行为不是未定义的:您的程序终止。使用什么样的结果代码,这是一个不同的问题。

[...] 只给出警告:'main' 的返回类型不是'int',但不是错误?

这就是它的实现方式。在旧的 C (C89) 中 - 以及一些较新的编译器 - 如果您省略函数的返回类型,它会被假定为 int(所以即使是警告看起来也有点问题)。

所以should应该在这个标准中被解释为强制性的,为什么gcc with swith --std=c99 违反了这个?

可能是的。请注意,GCC 是一个不符合标准的实现,除非您使用-ansi -pedantic,因此理论上,没有这些标志编译的任何程序都有未定义的行为。但这是理论......

【讨论】:

  • 是的,但是如果一个main没有返回类型,那么就会到达},这仍然是对标准的解释,不是吗。(当然,你的可能是原来的意思。 )
  • @larmbr main() 没有返回类型和没有return 0; 语句在其末尾没有任何关系。你可以同时做这两个,或者只做一个,或者一个都不做(最佳)。您误解了标准的措辞。
【解决方案4】:

这似乎是某种 C90 标准参考错误。我不知道您链接到的文档是否等同于实际的 ISO C90 标准。

显然,多年来,这个特定问题已从未定义变为未指定,再到明确定义。

在 ANSI-C“为 X3.J11 工作组”的早期草案中,您会发现以下文本:

2.1.2.2 托管环境

“程序终止”

从初始调用到 main 函数的返回是等价的 使用 main 返回的值调用 exit 函数 函数作为它的参数。如果主函数执行返回 不指定值,终止状态返回给主机 环境未定义

【讨论】:

  • 非常好的提示,谢谢。至于引用的c89标准,只是草稿,可能不是最终版,但我没找到。
  • @larmbr 实际上,您发布的链接看起来更像是某种 C90 后的草案,因为它列出了 1993 年的规范标准。
猜你喜欢
  • 2017-01-04
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 2021-10-17
  • 2012-11-12
  • 1970-01-01
相关资源
最近更新 更多