views:

468

answers:

6

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), true)
    {
        /* 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.

Fore more info: I'm posting my work at: http://www.abelenky.com/node/6 Its unfinished, but has more detail.

+6  A: 

if you don't return anything the program will return 0. See http://www.research.att.com/~bs/bs_faq2.html#void-main

ggf31416
+1  A: 

The compile may be smart enough to know that exit(0) is being called, which never returns so it's not needed.

John Boker
So far this seems correct. I'm still surprised that the compiler has special knowledge of the exit-function.
abelenky
Nope, it's simply that the standard specifies that it's legal to omit the return statement from main(). It implicitly returns 0 in that case. exit() has nothing to do with it.
jalf
See above: I can also omit the return statement from function foo, and it still compiles without warning. It is not unique to main.
abelenky
A: 

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.

abelenky
Are you compiling this as C or C++? C is much more relaxed about function calls, both parameters and return values.
jalf
I've tried in Visual Studio 2008, as both C++ and C (switches /TC and /TP) and on Linux/GCC with -ansi -Wall. All of these produce the same result. (note: for strict C, I changed 'true' to 1. Otherwise the program was the same)
abelenky
A: 

Because it's not an error -- it's undefined behavior. See section 6.9.1, paragraph 12 of the C99 standard:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

Thus, the compiler is free to do whatever it wants when seeing your code failing to return -- it can emit an error, a warning, or nothing at all. In the case of GCC, it by default compiles successfully with no warnings or errors. With the -Wall option, it emits a warning.

main() is special in C: it's the only function that's allowed not to return a value. The C standard says that if control reaches the end of main() without a return statement, it implicitly returns 0. This is only true for main(), all other non-void functions must return a value.

Section 5.1.2.2.3:

If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;10) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

Adam Rosenfield
See my comment below. The same result happens for function "foo".Instead, it seems that the compiler is treating exit(0) in a special way, not main.
abelenky
+1  A: 

From http://msdn.microsoft.com/en-us/library/k9dcesdd(VS.71).aspx

C++ Language Reference

exit Function

The exit function, declared in the standard include file STDLIB.H, terminates a C++ program.

The value supplied as an argument to exit is returned to the operating system as the program's return code or exit code. By convention, a return code of zero means that the program completed successfully.

Note You can use the constants EXIT_FAILURE and EXIT_SUCCESS, defined in STDLIB.H, to indicate success or failure of your program.

Issuing a return statement from the main function is equivalent to calling the exit function with the return value as its argument.


John MacIntyre
+6  A: 

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 implied return at 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++.

Michael Burr