我正在研究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)",我确实得到编译器错误.显然编译器知道"退出"是一个特殊的功能?这对我来说似乎很奇怪.
正如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++.
如果你没有返回任何东西,程序将返回0.请参阅http://www.research.att.com/~bs/bs_faq2.html#void-main