为什么void main()如此流行?

16
在C89/C99/C11中,在自由环境下,入口点函数是实现定义的。在托管环境中,它必须是严格符合规范程序的 int main 。大多数现代编译器会将 void main 视为错误。然而,我看到很多用户使用 void main。即使在不符合规范的编译器中允许使用,但为什么要这样做呢?我看不到任何实用理由测 void main 会优于 int main。甚至在C89中,省略 return 是未定义行为。
是否有历史上 void main 流行的原因?
我认为我的问题并非主要基于观点。已经在这个线程中提出了一些有效的想法,例如Microsoft的 void main 扩展,以及自Windows流行以来,以及C书籍重印不正确信息的结果。这些都是客观和历史性的原因。

8
也许是因为很多人不在意向操作系统返回失败/成功状态。 - m0skit0
7
可能与想要返回42有关,但没有人知道它的意义是什么。 - Hans Passant
9
有时候人们并不清楚自己在做什么。 - juanchopanza
5
请参考在C和C++中main()应该返回什么?以获得全面的解答。我的看法是,这种做法流行是因为(a)它允许你避免编写一行代码并且(b)微软说在Windows机器上这样做没问题。同时也意味着你不关心程序的退出状态 —— 你不是在一个退出状态很重要的脚本环境下编写代码。 - Jonathan Leffler
4
嗯,赫伯特·席尔德特(Herb Schildt)......http://www.lysator.liu.se/c/schildt.html - joop
显示剩余9条评论
3个回答

10
有没有关于void main流行的历史原因?
据我看,历史上流行void main的原因是,编写C语言编程书籍(特别是流行的书籍)时,标准尚未采用,而这些书籍在标准采用后(甚至是之前)出版。因此,许多C语言编程书籍包含返回类型为void的main函数声明。有时这些书籍被重新出版,但其内容并未修订。由于旧编译器通常支持使用返回类型为void的main函数声明,因此这种声明很流行。
此外,一些编译器生产商(甚至可能是Microsoft。如您所知,C#允许使用返回类型为void的Main函数声明。至少Borland C++允许使用void main)引入了自己的实现定义主函数声明。因此,具有返回类型为void的main函数声明成为一种流行的实现定义声明。所以,C语言编程书籍通常会提到这些带有实现定义main函数声明的流行编译器。

1
在第一个C标准之前,“void main()”并不是一个真正的选项,因为“void”在第一个C标准之前并不是C的一部分。半允许的是只有“main()” - 没有显式的返回类型 - 但是如果使用了该函数的值,则仍应从这些函数中返回一个值。人们没有看到使用“main()”的返回值的代码,尽管shell得到了它。 - Jonathan Leffler
1
如果我没记错的话(但我的记忆可能有误,我已经老了),一些旧的TurboC编译器在MSDOS上接受(或者可能更喜欢)void main()。这是在20世纪80年代初。 - Basile Starynkevitch
1
由于您已经基本掌握了正确的想法,所以对这个答案点赞。但我认为大多数这些书都是在标准化之后编写的。问题只是它们的作者无能,但设法出版了许多人阅读的书籍。在我看来,C语言的滥用和人们对C的误解(通常是负面看法)的大部分责任可以归咎于糟糕的教学,包括糟糕的书籍和糟糕的教师。 - R.. GitHub STOP HELPING ICE
4
我怀疑Turbo C是造成这种情况的最大罪魁祸首,它曾完全主导编译器,还允许使用void main()。即使今天,我们仍然会在stackoverflow上看到一些混淆的学生和糟糕教师发布此类main函数的问题。(主要因为某个国家的倒退教育体制似乎已经决定Turbo C仍然是最好的选择,而DOS则是未来的操作系统。) - Lundin
1
"废物中的精华"<3 - M.M
显示剩余3条评论

6

引用Lundin的答案,

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

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

编辑:

由于OP正在询问托管环境,因此我可以引用Keith的答案,

同样,C从未允许void main(),除非作为扩展;1989年引入void关键字的同一标准定义了两个main的标准定义:int main(void)和int main(int argc, char *argv[])。

以及Pochi的答案,

你通常想知道程序的退出状态,这就是为什么你有 int main() 的原因 -- 你返回你的退出状态。
从这两个令人信服的答案中,我可以得出以下结论:在 C89/C99/C11 时期,C 可能不允许 void main,但对于由爱好者、学习者和初学者创建的小型程序,他们可能不关心此阶段的返回值,因此 void main 变得流行。

我不明白这个回答如何解决问题。 - juanchopanza
@juanchopanza OP问道:“我看不出为什么void main会优于int main。”这就是原因。 - shauryachats
@volerag,我在我的问题中已经提到了独立部分。我是在询问托管环境的情况。 - user4694281
作为曾经写过这个答案的人,我现在有点不太确定 - 标准实际上可以被解释为“任何实现定义的方式都可以”,即使是针对托管环境。但是你必须意识到实现定义的含义,它的意思是“编译器在这种情况下可以随意处理,只要它记录下来”。如果没有关于某个非标准形式的main的编译器文档,那么它应该被视为未定义行为。 - Lundin
在独立环境下,你不应该首先调用一个 main 函数。标准明确定义了 main 函数,使用不同类型的 main 函数只会让人感到混乱。将其称为 kmainkernel_main 或类似的名称,并使其返回类型为 void,这样就不会因此受到质疑了。 - DevSolar

2
如果您使用的是*NIX或MAC,请按照以下步骤操作。
  1. Copy following code to test1.c

    void main() {
    }
    
  2. Compile code in command line

    cc test1.c
    
    gcc test.c
    
  3. Run following

    ./a.out
    
  4. Run following (this will show you what is returned by your program

    echo $?
    
  5. Save this code to test2.c

    void main() {
        int i = 5;
    }
    
  6. Repeat 2, 3 and 4 for test2.c

这就是为什么不推荐这样做。

为什么会流行呢?除了上面提到的,我不知道其他答案。不过我有一个问题:K&R第一版是使用void main()还是int main()


5
K&R第一版不可能使用void main,因为在当时尚未发明void(直到C++诞生)。K&R第一版在许多地方使用隐式的“int”。 - Jens
感谢 @Jens 的回答。 - user4580220

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接