为什么C和c ++中的main函数的类型留给用户定义?

ANU*_*OYI 16 c c++ program-entry-point

为什么main()用户定义了功能?

我什么时候会使用void main()int main()

Lun*_*din 39

编辑这个答案并不尽可能完整,因为它并没有真正解决这个奇怪的句子"或者以某种实现定义的方式".我现在写了一个更完整的答案,也解决了C90,C11和C++.编辑结束

这是C标准所说的(ISO C 9899:1999):

5.1.2.1独立环境

在独立环境中(可以在没有操作系统任何好处的情况下执行C程序),程序启动时调用的函数的名称和类型是实现定义的./ .. /程序终止在独立环境中的影响是实现定义的.

5.1.2.2托管环境

不需要提供托管环境,但如果存在,则应符合以下规范.

5.1.2.2.1程序启动

程序启动时调用的函数名为main.该实现声明此函数没有原型.它应该使用int的返回类型定义,并且没有参数:

int main(void){/*...*/}

或者有两个参数(这里称为argc和argv,虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):

int main(int argc,char*argv []){/*...*/}

C++标准中的文本或多或少相同.注意,文本中的"程序启动"是托管环境的子条款.

这意味着:

  • 如果您的程序在无主机环境中运行(您的程序是嵌入式系统或操作系统),则它可能具有任何返回类型.void main()是最常见的.

  • 如果您的程序在托管环境中运行(在操作系统之上),则main()必须返回int,并且可能具有其他参数.

  • +1,有效答案.但也许还有一些解释.在独立环境中,`main`的返回类型是*实现定义*:这并不意味着由程序员来决定,而是由平台强加*.编译器手册应该指定这个.在托管环境中,选择实际上是在参数的两个给定备选方案之间.如果有参数,则这些参数必须正好为两个且具有给定类型.顺便说一下,在我看来你错过了`````argv`. (6认同)
  • 检查标准,你实际上跳过了该部分最后一个短语的延续:"或等效; 9)或其他一些实现定义的方式." 这意味着编译器实现可能具有不同的调用约定.一些编译器例如允许第三个参数"char*envp []".但同样必须在编译器文档中指定. (2认同)
  • C标准允许`main`的返回类型不是`int`.5.1.2.1的措辞含糊不清,但5.1.2.2.3以"如果**主**函数的返回类型是与int兼容的类型......"开头. (2认同)
  • @Lundin:我的观点是你的答案中有一个事实错误的陈述.符合C的实现可以记录并允许`void main(void)`.(并且您描述的行为不会使Turbo C不符合;定义`void main()`如果实现没有记录它具有未定义的行为,但它不需要诊断.) (2认同)

Lig*_*ica 7

Lundin关于C是正确的,但在C++中,措辞是完全不同的,以产生差异:

[C++11: 3.6.1/1]:程序应包含一个名为的全局函数main,它是程序的指定开始.实现定义是否需要独立环境中的程序来定义main函数.

[C++11: 3.6.1/2]:实现不应预定义该main功能.此功能不应过载.它应该具有类型的返回类型int,否则其类型是实现定义的[...]

第一个粗体通道不会覆盖或取消第二个.

mainint总是在C++中返回.

  • *你可以使用`void` ...除非你不能.* (4认同)

Joh*_*ode 5

返回类型main由实现决定,而不是程序员.检查编译器文档以查看合法签名的用途main.不要以为那void main()是其中之一.在托管环境中,main通常返回int.在自由标准环境中,入口点甚至可能不会被命名main,但其返回类型仍将由实现决定,而不是程序员.


Sha*_*fiz -1

许多编译器不支持 void main(),因此您应该始终使用 int main()。

  • -1 这是错误的。如果您的程序是嵌入式系统或操作系统,它将使用 void main(),根据 C/C++ 标准,这完全没问题。请参阅下面我的进一步回答。 (8认同)