当前位置:  开发笔记 > 编程语言 > 正文

为什么没有编译器错误的main()没有返回结束?

如何解决《为什么没有编译器错误的main()没有返回结束?》经验,为你挑选了2个好方法。

我正在研究C-brain预告片:编写标准的Hello-World程序,没有分号.

到目前为止我的最佳答案是:

int main(void)
{
    if (printf("Hello World!\n"), exit(0), 0)
    {
        /* do nothing */
    }
}

但我不明白为什么我没有得到编译器错误(Visual Studio):

error C4716: 'main' : must return a value

我已尝试使用声明的返回类型的其他函数,但缺少return语句,并得到此编译器错误.


请注意,我也尝试过:

int foo(void)
{
    if (printf("Hello World!\n"), exit(0), true)
    {
        /* do nothing */
    }
}

int main(void)
{
    foo();
}

并且不要在foo上得到编译器错误.如果我删除"退出(0)",我确实得到编译器错误.显然编译器知道"退出"是一个特殊的功能?这对我来说似乎很奇怪.



1> Michael Burr..:

正如Jens在评论中指出的那样,发布的代码没有表现出未定义的行为.这里的原始答案是不正确的,甚至似乎都没有回答这个问题(几年之后重新阅读所有内容).

这个问题可以概括为"为什么MSVC不会main()在与其他功能相同的情况下发出警告C4716 "?

请注意,诊断C4716是警告,而不是错误.就C语言而言(无论如何从标准的角度来看),从来没有要求诊断非错误.但这并没有真正解释为什么存在差异,这只是一种技术性,可能意味着你不能抱怨太多......

为什么MSVC不会发出警告以main()解决其他功能的真正原因只能由MSVC团队的某个人来回答.据我所知,文档并没有解释差异,但也许我错过了一些东西; 所以我所能做的就是推测:

在C++中,该main()函数被特别处理,因为return 0;在结束括号之前存在隐式.

我怀疑微软的C编译器在C模式下进行编译时提供相同的处理方法(如果查看汇编代码,即使没有清除EAX寄存器return 0;),因此就编译器而言,没有理由发布警告C4716.请注意,Microsoft的C模式符合C90标准,而不符合C99标准.在C90'跑掉'结束' main()有未定义的行为.但是,始终返回0满足未定义行为的低要求,因此没有问题.

因此,即使问题中的程序确实没有运行main()(导致未定义的行为),仍然不会有警告.


原来,不是那么好的答案:

在ANSI/ISO 90 C中,这是未定义的行为,因此MS确实应该产生错误(但标准不要求它们).在C99中,标准允许return在main()结尾隐含- 与C++一样.

因此,如果将其编译为C++或C99,则没有错误,它也是相同的return 0;.C90导致未定义的行为(不需要诊断).

有趣的是(好吧,也许不是),在几个编译器(VC9,VC6,GCC 3.4.5,Digital Mars,Comeau)中,我尝试使用我的基本,主要是默认选项集(我几乎总是使用的环境 - 代码片段的n-dirty测试)当编译为C++程序时,唯一警告缺少返回语句的编译器是VC6(VC6在编译C时没有抱怨).

如果函数未命名,大多数编译器会抱怨(警告或错误)main.编译C时的数字火星没有,GCC不适用于C或C++.



2> ggf31416..:

如果你没有返回任何东西,程序将返回0.请参阅http://www.research.att.com/~bs/bs_faq2.html#void-main

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有