17

Often times I see the infamous void main() around the forums and almost immediately a comment following the question telling the user to never use void main() (which I am in complete agreement with). But where is the origin of void main()?

Why am I still seeing newer people pick up the bad habit of having main return nothing when the proper way is to return an int. I understand WHY this method is wrong as explained in this question and multitudes of others, but I don't how this method of declaring main came about or even why it is still taught to some students.

Community
  • 1
  • 1
Syntactic Fructose
  • 15,445
  • 16
  • 74
  • 158

7 Answers7

10

Even Bjarne Stroustrup has written void main, in C++, so it's indeed a common anti-meme, and an old one, predating Java and other contemporary languages that support void main. Of course Bjarne has also written that void main has never been part of either C or C++. However, for this latter statement (in his FAQ), at least as of C99 it looks as if Bjarne is wrong, because the N869 draft of the C99 standard says in its §5.1.2.2.3/1 that

“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; 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.”

And earlier, in its §5.1.2.2.1/1 it states about the signature of main,

“ or in some other implementation-defined manner.”

A return type “not compatible with int” could, for example, be void.

So, while this is not a complete answer (I doubt that historical sources about this are available on the net), at least it goes some way towards correcting the assumptions of the question. It is not the case that void main is a complete abomination in C and C++. But in C++ it's invalid: it's a C thing that's not supported in a hosted C++ implementation.

Cheers and hth. - Alf
  • 135,616
  • 15
  • 192
  • 304
  • 2
    The history has not entirely disappeared. The concept of command execution in its current form basically derives from Multics (see www.multicians.org) whose command shell could basically invoke any PL/I procedure (typically), passing it arguments as character strings. There was no return code. Unix picked up this model. Dennis Ritchie describes the evolution of the shell command execution model in this essay, from 1979: http://cm.bell-labs.com/cm/cs/who/dmr/hist.html You'll see from that that user processes called exit() to terminate; returning was a later innovation. – rici Dec 19 '12 at 15:29
4

I have been a victim of this problem, so I think I can tell you why this happens, During our C lectures the faculties have to start our lectures using a sample program (probably "Hello World") and for that they have to use main() method.

But since they don't want to confuse students and also they don't want to get into the complexity of teaching the return types and return statements at the very start of their C programming lessons, they use(and also ask us to use) void main() and tell us to assume this as the default type till we study functions and return types in detail.

Hence this leads to develop a wrong habit of using void main() from the very first lecture of our C-Programming.

Hope that explains u well about why most of the Computer Programmers especially the newer ones pick up this bad practice.

Cheers, Mayank

user1606191
  • 541
  • 1
  • 6
  • 13
  • 3
    That sounds like a very confusing way of not confusing students. – juanchopanza Dec 19 '12 at 07:19
  • 1
    Which is absolutely ridiculous. Replacing `void` with `int` and simply saying, "We'll get into what int means later" would suffice, especially since the very next thing they'll learn is probably what ints are. – derpface May 13 '14 at 23:17
2

Personally I think it's the following: K&R C didn't require to specify a return type and implicitly assumed it to be int and at the same time the examples in K&R didn't use a return value.

For example the first code in K&R first edition is the following:

#include <stdio.h>

main() 

{
   printf("Hello World\n");
}

So it's no wonder that people reading this later (after a void type was added to the language as an extension by some compilers) assumed that main actually had a void return statement.. I would've done the same thing.

Actually K&R does say later:

In the interests of simplicity, we have omitted return statements from our main functions up to this point, but we will include them hereafter, as a reminder that programs should return status to their environment.

So that's just another example of what happens when you write incorrect code and include a disclaimer later under the assumption that people will read everything before doing stupid things ;)

Voo
  • 26,852
  • 9
  • 70
  • 145
2

As one author amongst a number of others, Herbert Schildt wrote some popular but not necessarily high quality books which espoused the idea.

One egregious example is his The Annotated C Standard. He quotes the ISO/IEC 9899:1990 standard on left-hand pages and provides annotations on the right-hand pages. When he quotes section 5.1.2.2.1 Program Startup, it says:

The function called at program startup is named main. The implementation declares no prototype for this function. It can be defined with no parameters:

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

or with two parameters (…):

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

This doesn't include the 'or in some other implementation-defined manner' clause that was added to C99.

Then, in the annotations, he says:

Interestingly, there is no prototype for main() declared by the compiler. You are therefore free to declare main() as required by your program. For example, here are three common methods of declaring main():

void main(void)  /* no return value, no parameters */

int main(void)   /* return a value, no parameters */

/* return a value and include command-line parameters */
int main(int argc, char *argv[])

The first variation is not allowed by the C90 standard, despite what he says, but innocent readers might be confused.

Note that section 5.1.2.2.3 Program termination says:

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. If the main function executes a return that specifies no value, the termination status returned to the hosted environment is undefined.

Since you'd find that exit takes an int argument, it is clear from this that the return type of main should be int.

The commentary says:

In most implementations, the return value from main(), if there is one, is returned to the operating system. Remember, if you don't explicitly return a value from main() then the value passed to the operating system is, technically, undefined. Though most compilers will automatically return 0 when no other return value is specified (even when main() is declared as void), you should not rely on this fact because it is not guaranteed by the standard.

Some of this commentary is so much bovine excrement, a view in which I am not alone in holding. The only merit in the book is that it includes almost all of the C90 standard (there's one page missing from the description of fprintf — the same page got printed twice) for far less than the cost of the standard. It's been argued that the difference in price represents the loss of value from the commentary. See Lysator generally for some information on C, and Clive Feather's review of The Annotated C Standard.

Another of his books is C: The Complete Reference, which made it to at least the 4th Edition. The 3rd Edition used void main() extensively; this may have been cleaned up by the 4th Edition, but it's sad it took that many editions to get such a fundamental issue correct.

Community
  • 1
  • 1
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
2

Embedded programs that run on bare metal, that is without an operating system, never return. On power up, the reset vector jumps indirectly (there is some memory initialization that happens first) to main and inside of main, there is an infinite while (1){} loop. Semantically, a return value for main doesn't make sense.

Mark Lakata
  • 18,024
  • 5
  • 88
  • 112
1

Possible reasons:

  • Java programmers used to writing public static void main(...).
  • Missing return statement could have some assume main does't return, although it implicitly returns 0.
  • In C you were able to write main() with no return type, and it would be int by default. Maybe some assume a missing return type is equivalent to a void.
  • Bad books / teachers?
Luchian Grigore
  • 236,802
  • 53
  • 428
  • 594
  • 7
    I don't really think the first is a possible reason for its origin, since people have been using `void main()` for longer than Java has existed. – Brian Campbell Dec 19 '12 at 06:51
  • interesting points, weird how such a bad method has its origins unknown..... from what i can see most of these bad methods seem to relate all back to c standards, wonder if there are any other possible reasons for `void main`. – Syntactic Fructose Dec 19 '12 at 06:53
  • I think it's mainly the last point. From poking around, it seems a lot of bad C books utilize `void main`. – Yuushi Dec 19 '12 at 07:07
1

From a C++ point-of-view, 3 sources of confusion exist:

  • Fundamentalist PC/desktop programmers who fanatically and blindly preach int main() without actually knowing the complete picture in the standard themselves. C and C++ have completely different rules for how main() should be declared in freestanding systems (when programming bare metal embedded systems or operative systems).
  • The C language, which historically has had different rules compared with C++. And in C, the rules for main() have changed over time.
  • Legacy compilers and coding standards from the dark ages, including programming teachers stuck in the 1980s.

I'll address each source of confusion in this answer.

The PC/desktop programmers are problematic since they assume that hosted systems are the only systems existing and therefore spread incorrect/incomplete propaganda about the correct form of main(), dogmatically stating that you must use int main(), incorrectly citing the standard while doing so, if at all.

Both the C and C++ standards has always listed two kinds of systems: freestanding and hosted.

In freestanding implementations, void main (void) has always been allowed in C. In C++, freestanding implementations are slightly different: a freestanding implementation may not name the entry function main() or it has to follow the stated forms that return int.

Not even Bjarne Stroustrup manages to cite the standards or explain this correctly/completely, so no wonder that the average programmer is confused! (He is citing the hosted environment sub-chapter and fails to cite all relevant parts of it).

This is all discussed in detail with references to the standard(s) here, Bjarne and others please read.

Regarding void main (void) in hosted systems, this originates way back, from somewhere in the dark ages before the ISO C standard, where everything was allowed.

I would suspect that the major culprit behind it is the Borland Turbo C compiler, which was already the market leader when ISO C was released in 1990. This compiler allowed void main (void).

And it should be noted that void main (void) for hosted implementations was implicitly forbidden in C90 for hosted systems, no implementation-defined forms were allowed. So Turbo C was never a strictly conforming implementation. Yet it is still used in schools (particularly in India)! Teaching every student incorrect programming standards from scratch.

Since C99, void main (void) and other forms became allowed in C, because of a strange sentence which was added: "or in some other implementation-defined manner". This is also discussed in the linked answer above, with references to the C99 rationale and other parts of the C standard that are assuming that a hosted system main() may not return int.

Therefore in C, void main (void) is (arguably) currently an allowed form for hosted implementations, given that the compiler documents what it does. But note that since this is implementation-defined behavior, it is the compiler that determines whether this form is allowed or not, not the programmer!

In C++, void main (void) is not an allowed form.

Community
  • 1
  • 1
Lundin
  • 155,020
  • 33
  • 213
  • 341