void main(void)–the argument continues…

For, what must be, years now the perpetual argument among programmers in various forums  resurfaces about the legality, or not, of the use of void as the return type for the main function.

I generally try and ignore these arguments as it seems such a trivial point, but maybe it’s because yet another birthday has just passed it’s time to put my two-penneth in.

Before we start, hopefully we all agree that the following code is an abomination:

main() { }

You would probably be more shocked if I told you that this comes from a fairly recent book (2008) Programming 32-bit Microcontrollers in C. Shame on you all.

The argument against the use of void has weighty backing, notability the creator of C++, no other than Bjarne Stroustrup himself. The following is taken from his very useful C++ Style and Technique FAQ:

The definition

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

is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts

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

and

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

He then goes on to state;

A conforming implementation may provide more versions of main(), but they must all have return type int. The int returned by main() is a way for a program to return a value to “the system” that invokes it. On systems that doesn’t provide such a facility the return value is ignored, but that doesn’t make “void main()” legal C++ or legal C. Even if your compiler accepts “void main()” avoid it, or risk being considered ignorant by C and C++ programmers

Ouch; ignorant, moi. I take that as a personal insult Winking smile

Unfortunately, what Prof. Strousturp is failing to recognise (or possibly acknowledge) is the hundreds, if not thousands, of embedded programmers out there. For example, in the text above the key line is:

The int returned by main() is a way for a program to return a value to “the system” that invokes it.

Deeply embedded systems don’t have a “system” that invokes it, so there is nowhere for it return to and thus having an int return type is actually misleading.

However, I hear you shout, the standard says it must be; not so.

Both the C and C++ standards define two types of execution environments

  • Freestanding
  • Hosted

To quote the C standard (5.1.2.1):

In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation defined.

and the C++ standard (3.6.1)

It is implementation-defined whether a program in a freestanding environment is required to define a main function

So there you have it your honour, embedded systems are freestanding, and as so I can call the startup anything, therefore void main(void) is perfectly legal.

So I would argue, not understanding that void main(void) is perfectly acceptable in for freestanding environment is in risk of being considered ignorant of the finer details of embedded programming.

I know this won’t be the end of it but next time someone starts down this line, just ask them to explain the difference between a freestanding and hosted environment (makes a nice interview question as well!).

Dislike (0)

About Niall Cooling

Co-Founder and Director of Feabhas since 1995. Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking. His current interest lie in IoT Security and Agile for Embedded Systems.
This entry was posted in C/C++ Programming and tagged . Bookmark the permalink.

8 Responses to void main(void)–the argument continues…

Leave a Reply