只有书籍作者似乎知道允许返回类型为void
for的地方main()
。C++ 标准完全禁止它。
C标准说标准形式是:
int main(void) { ... }
和
int main(int argc, char **argv) { ... }
允许参数类型的替代但等效的声明形式(当然,名称是完全自由的,因为它们是函数的局部变量)。
C标准确实为“以其他一些实现定义的方式”做出了小的规定。ISO/IEC 9899:2011 标准规定:
5.1.2.2.3 程序终止
如果main
函数的返回类型是与 兼容的类型int
,则从函数的初始调用返回main
相当于以exit
函数返回的值main
作为参数调用函数;11)到达}
终止main函数的返回值为0。如果返回类型与 不兼容int
,则返回给宿主环境的终止状态是未指定的。
11)根据 6.2.4,在 main 中声明的具有自动存储持续时间的对象的生命周期将在前一种情况下结束,即使在后者中它们不会有。
这清楚地允许int
不退货,但清楚地表明它没有被指定。因此,某些实现void
可能允许将其作为返回类型main()
,但您只能从文档中找到它。
(虽然我引用的是 C2011 标准,但在 C99 中基本上是相同的词,我相信 C89,尽管我的文字在办公室,但我不是。)
顺便说一句,标准的附录 J 提到:
J.5 通用扩展
以下扩展在许多系统中广泛使用,但不能移植到所有实现中。包含可能导致严格符合的程序无效的任何扩展都会导致实现不符合。此类扩展的示例是新关键字、标准头文件中声明的额外库函数或名称不以下划线开头的预定义宏。
J.5.1 环境参数
在托管环境中,该main
函数接收第三个参数 ,char *envp[]
该参数指向一个以空结尾的指针数组char
,每个指针指向一个字符串,该字符串为程序的执行提供有关环境的信息(5.1.2.2.1 )。
为什么void main()
有效?
问题观察到void main()
有效。它“有效”是因为编译器会尽力为程序生成代码。诸如 GCC 之类的编译器会针对 的非标准形式发出警告main()
,但会对其进行处理。链接器不太担心返回类型;它只需要一个符号main
(或者可能_main
,取决于系统),当它找到它时,将它链接到可执行文件中。启动代码假定main
已以标准方式定义。如果main()
返回到启动代码,它会像函数返回一个 一样收集返回值int
,但该值很可能是垃圾。因此,只要您不寻找程序的退出状态,它似乎就可以工作。