I’m working on a C-brain teaser: Write the standard Hello-World program, without semi-colons.
My best answer so far is:
int main(void) { if (printf('Hello World!\n'), exit(0), 0) { /* do nothing */ } }
But I don’t understand why I don’t get compiler error (Visual Studio):
error C4716: 'main' : must return a value
I’ve tried other functions with a return-type declared, but missing a return-statement, and get this compiler error.
Note that I’ve also tried:
int foo(void) { if (printf('Hello World!\n'), exit(0), true) { /* do nothing */ } } int main(void) { foo(); }
And don’t get a compiler error on foo. If I remove the ‘exit(0)’, I do get the compiler error. Apparently the compiler has knowledge that ‘exit’ is a special function? This seems very odd to me.
As Jens pointed out in a comment, the posted code does not exhibit undefined behavior. The original answer here isn’t correct and doesn’t even really seem to answer the question anyway (on re-reading everything a few years later).
The question can be summed up as, ‘why doesn’t MSVC issue warning C4716 for
main()in the same circumstances it would for other functions’?Note that diagnostic C4716 is a warning, not an error. As far as the C language is concerned (from a standards point of view anyway), there’s never a requirement to diagnose a non-error. but that doesn’t really explain why there’s a difference, it’s just a technicality that may mean you can’t complain too much…
The real explanation for why MSVC doesn’t issue the warning for
main()when it does for other functions can really only be answered by someone on the MSVC team. As far as I can tell, the docs do not explain the difference, but maybe I missed something; so all I can do is speculate:In C++, the
main()function is treated specially in that there’s an implicitreturn 0;just before the closing brace.I suspect that Microsoft’s C compiler provides the same treatment when it’s compiling in C mode (if you look at the assembly code, the EAX register is cleared even if there’s no
return 0;), therefore as far as the compiler is concerned there is no reason to issue warning C4716. Note that Microsoft’s C mode is C90 compliant, not C99 compliant. In C90 ‘running off the end’ ofmain()has undefined behavior. However, always returning 0 meets the low requirements of undefined behavior, so there’s no problem.So even if the program in the question did run off the end
main()(resulting in undefined behavior) there still wouldn’t be a warning.Original, not so good answer:
In ANSI/ISO 90 C, this is undefined behavior, so MS really should produce an error (but they aren’t required to by the standard). In C99 the standard permits an impliedreturnat the end of main() – as does C++.So if this is compiled as C++ or C99, there’s no error and it’s the same as
return 0;. C90 results in undefined behavior (which does not require a diagnostic).Interestingly (well, maybe not), of the several compilers (VC9, VC6, GCC 3.4.5, Digital Mars, Comeau) I tried this on with my basic, mostly default options set (the environment I pretty much always use for quick-n-dirty testing of code snippets) the only compiler that warns about the missing return statement is VC6 when compiling as a C++ program (VC6 does not complain when compiling for C).
Most of the compilers complain (a warning or error) if the function is not named
main. Digital Mars when compiling for C does not and GCC doesn’t for C or C++.