返回主函数类型

可能重复:
main()应该在C / C ++中返回什么?
void main和int main之间的区别?

我一直在使用C中的main方法

void main(){ // my code } 

它对我来说非常好用。 我也知道其他int返回类型:

 int main(void) int main() int main(int argc, char *argv[]) 

但我找不到任何资源说我可以使用void作为返回类型。 每本书都建议返回类型必须是int ,否则它将被省略。 那么为什么void main()工作?

这取决于我使用的C版本吗? 或者它是否有效,因为我使用的是C ++ IDE? 请具体回复C而不是C ++。

只有书籍作者似乎知道允许main()的返回类型为void的地方。 C ++标准完全禁止它。

C标准说标准forms是:

 int main(void) { ... } 

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

允许参数类型的替代但等效forms的声明(当然,名称完全是自由裁量的,因为它们是函数的局部变量)。

C标准确实为’以某种其他实现定义的方式’做了一些小规定。 ISO / IEC 9899:2011标准说:

5.1.2.2.3程序终止

如果main函数的返回类型是与int兼容的类型,则从初始调用返回main函数等效于调用exit函数,并将main函数返回的值作为其参数; 11)到达终止main函数的}返回值0.如果返回类型与int不兼容,则返回到主机环境的终止状态未指定。

11)根据6.2.4,在主要情况下声明的具有自动存储持续时间的物体的寿命将在前一种情况下结束,即使它们在后者中没有。

这显然允许非int返回,但明确指出它没有指定。 因此,某些实现可能允许void作为main()的返回类型,但是您只能从文档中找到它。

(虽然我引用的是C2011标准,基本上相同的单词都是在C99中,我相信C89虽然我的文字是在办公室而我不是。)

顺便说一下,标准的附录J提到:

J.5常用扩展

以下扩展在许多系统中广泛使用,但不能移植到所有实现。 包含可能导致严格符合程序无效的任何扩展会导致实现不一致。 此类扩展的示例包括新关键字,标准标头中声明的额外库函数,或者名称不以下划线开头的预定义宏。

J.5.1环境参数

在托管环境中, main函数接收第三个参数char *envp[] ,该参数指向以null结尾的char指针数组,每个指针指向一个字符串,该字符串提供有关此执行的环境的信息。程序(5.1.2.2.1)。

为什么void main()有效?

问题是观察到void main()有效。 它“有效”,因为编译器尽力为程序生成代码。 像GCC这样的编译器会警告main()的非标准forms,但会处理它们。 链接器不太担心返回类型; 它只需要一个符号main (或者可能是_main ,取决于系统),当它找到它时,将它链接到可执行文件中。 启动代码假定main已以标准方式定义。 如果main()返回到启动代码,它会收集返回的值,就好像函数返回一个int ,但该值可能是垃圾。 因此,只要您不查找程序的退出状态,它似乎有效。

从马的嘴里 :

5.1.2.2.1程序启动

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

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

或者使用两个参数(这里称为argcargv ,尽管可以使用任何名称,因为它们是声明它们的函数的本地名称):

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

或同等学历; 9)或以其他一些实现方式定义。


9)因此,int可以替换为定义为int的typedef名称,或者argv的类型可以写为char ** argv,依此类推。

漏洞是“其他一些实现定义的方式”。 实现可以允许main返回void (或任何其他类型),但它必须明确记录允许这样的签名。 否则行为是未定义的,这意味着编译器可以执行任何想要的操作。 程序可以毫无问题地执行。 它可能会执行,但会使环境处于不良状态。 退出时可能会崩溃。 它可能根本无法加载。

它取决于您使用的编译器,但void main不能在任何地方编译。 我见过编译器无法使用void main编译程序。 我不记得具体情况(对于c),但我确信这发生在g ++中(是的,我知道这是c ++)。

标准要求main()返回int ,但是很多C编译器允许你将main()的返回类型指定为void

我建议你养成返回int的习惯。 添加一个

 return 0; 

到你的main()结束是不是太费力。

我在C89中是可以接受的,但它不再被认为是“安全的”。 在C99下,它已不再可接受。

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284376&answer=1044841143