7

可能重复:
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++。

4

5 回答 5

11

只有书籍作者似乎知道允许返回类型为voidfor的地方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,但该值很可能是垃圾。因此,只要您不寻找程序的退出状态,它似乎就可以工作。

于 2012-06-06T14:01:25.883 回答
2

马口中

5.1.2.2.1 程序启动

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

    int main(void) { /* ... */ }
或带有两个参数(这里称为argcand argv,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):

    int main(int argc, char *argv[]) { /* ... */ }
或同等学历; 9) 或以其他一些实现定义的方式。
9) 因此,int 可以替换为定义为 int 的 typedef 名称,或者 argv 的类型可以写为 char ** argv,等等。

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

于 2012-06-06T14:09:38.297 回答
0

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

于 2012-06-06T14:01:02.220 回答
0

标准要求main()返回int,但许多 C 编译器允许您指定main()as的返回类型void

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

return 0;

到最后你main()是不是太努力了。

于 2012-06-06T14:03:14.043 回答
-1

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

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

于 2012-06-06T14:03:55.947 回答