C / C++ main function prototypes

There seems to be some fundamental misunderstanding about the function prototype for the “main” function in C and C++. More specifically what type this function should return. I see so many programmers use void as the return type. People, I’m sorry to tell you but that’s just plain wrong!

The C/C++ standards are very (VERY) clear about the prototype for the main function. It can be one of the following two (and only the following two) formats:

int main(void) { /*...*/ }

and

int main(int argc, char *argv[]) { /*...*/ }

Any other prototype is ill-defined and will result in undefined behaviour. Don’t be fooled into thinking that it must be okay to have void as the return type because, if it wasn’t the compiler would chuck an error. Actually, the C / C++ standard does not require the compiler to do this. All the standard states regarding this matter is:

“If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined.”

Now, the chances are that you’ll never see the effect of your mistake directly. By the time the brown stuff hits the fan, your program has likely ended. No, it won’t be you who gets caught out, it’ll be the user of your program who suffers at your hands.

You see, all processes return an exit code, which just happens to be the value returned from main. The actual value of this code is completely arbitrary but, nevertheless, the OS will expect it and the C/C++ runtime will deliver it – even if you haven’t provided it with one!

By de-facto standard, zero is returned for success and any other value means failure. If you define your function to return void, what will be returned will normally be the last value stored in the accumulator register. This is because the accummulator is normally used to store the return value of a function. The chances are that in our case this value will not be zero. In fact, it’ll be whatever was left in the accumulator when the program exited.

Anyone attempting to write a script to use your program is going to have a head-scratchingly hard time trying to work out why your program randomly seems to fail when they test the result code of your process. They will discover that it appears to be an arbitrary value. Guess what, it is! Your decision to completely ignore a simple standard will have properly ruined someone’s day.

Interestingly, whilst the main function MUST be defined to return an int, in C++ you don’t have to actually return anything from main. The main function is treated as a special case; whereas, if you omit a return value the C++ runtime will automatically return zero for you. In other words, the following is about the smallest and, yet, still perfectly valid (if pointless) C++ program one can possibly write.

int main() {}

NB. This does NOT apply to the C programming language, where you MUST always return a value from main.

Whether you consider it good practice to have a function defined as returning an int that don’t actually return a specific value is entirely up to you, but in this one specific case you are allowed to violate what is normally a fundamental rule; functions defined as returning values MUST return values!

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.