19

Why is main() a user defined function ?

When will I use void main() and int main()?

Azeem
  • 11,148
  • 4
  • 27
  • 40
ANUP BISOYI
  • 191
  • 1
  • 3
  • The type of *every* non-library function is left to the user to define. `main` is different in that the set of choices is narrower. – Keith Thompson Sep 03 '13 at 02:02

6 Answers6

40

EDIT This answer is not as complete as it could be since it doesn't really address the strange sentence "or otherwise in some implementation-defined manner". I have now written a more complete answer which also addresses C90, C11 and C++. END OF EDIT

Here is what the C standard says (ISO C 9899:1999):

5.1.2.1 Freestanding environment

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. / .. / The effect of program termination in a freestanding environment is implementation-defined.

5.1.2.2 Hosted environment

A hosted environment need not be provided, but shall conform to the following specifications if present.

5.1.2.2.1 Program startup

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

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

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

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

The text in the C++ standard is more or less identical. Please note that "Program startup" in the text is a subclause to hosted environment.

This means:

  • If your program is running in a hostless environment (your program is an embedded system or an operative system), it may have any return type. void main() is most common.

  • If your program is running in a hosted environment (on top of an OS), main() must return int, and may have additional parameters.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 6
    +1, for the valid answer. But perhaps some more explanation. On freestanding environments the return type of `main` is *implementation defined*: this doesn't mean that it is up to the programmer to decide that, but that it is *imposed* by the platform. The compiler manual should specify this. On hosted environments the choice is really between the two given alternatives for the parameters. If there are parameters these must be exactly two and with the given types. BTW, it seems to me that you missed a `*` for `argv`. – Jens Gustedt Mar 14 '11 at 09:20
  • @Jens The function may be named anything, take anything as parameters, and return anything. Naturally this is system-dependant, but the most commonly used for is void main() which contains an eternal for(;;) loop. – Lundin Mar 14 '11 at 09:25
  • 2
    Checking the standard, you actually skipped the continuation of the last phrase of the section: "or equivalent;9) or in some other implementation-defined manner." Meaning that here again the compiler implementation may have a different calling convention. Some compiler e.g allow a third argument "char *envp[]". But again this must be specified in the compiler documentation. – Jens Gustedt Mar 14 '11 at 09:25
  • @Jens Thanks for pointing out the missing *. Fixed. The scripts of the cite absorbed it to make the text italian :) – Lundin Mar 14 '11 at 09:26
  • @Lundin. yes, but I wanted to emphasize on the fact that it is the compiler implementor and not the programmer who decides on the signature. The question of the OP left me the impression him thinking that it was him who decides. – Jens Gustedt Mar 14 '11 at 09:27
  • @Jens Yes I intentionally left that part out as it confuses the reader. It says "or equivalent;9) or in some other implementation-defined manner." This had plenty of people confused about the standard, thinking it referred to the way main() should be declared, while it only refers to the parameters of main(). – Lundin Mar 14 '11 at 09:28
  • @Lundin. Indeed, it is not the clearest. But in any case, there also it says "implementation defined", so only the compiler implementor has the possibility to do something else, not the programmer. – Jens Gustedt Mar 14 '11 at 09:35
  • 2
    The C standard allows the return type of `main` to be something other than `int`. The wording of 5.1.2.1 is ambiguous, but 5.1.2.2.3 starts with "If the return type of the **main** function is a type compatible with int ..." – Keith Thompson Feb 20 '12 at 10:12
  • 1
    @KeithThompson 5.1.2.1 specifies a freestanding environment, so it has nothing to do with 5.1.2.2.3, which only applies to a hosted environment. And yes, the standard allows implementation-defined ways to declare main, as well as unspecified behavior when returning another type than int. But these are still decisions that will be made by the compiler implementer and not by the programmer, so I feel it is best to leave all such special cases out of this answer. – Lundin Feb 20 '12 at 10:43
  • 1
    @Lundin: My mistake; I meant that 5.1.2.2.1 is ambiguous. But your statement that "**main() *must* return int**" is correct for C++ but incorrect for C; a C hosted implementation *may* permit `void main(void)`, for example. – Keith Thompson Feb 20 '12 at 10:49
  • @KeithThompson Yes, but the question is "why is the type of main left to the user to define". It isn't up to the user. Also, types like `void main()` are only allowed if the compiler documents it, as it must do with all implementation-defined behavior. Classic Borland Turbo C for example, allowed void main(), but didn't document how or why, so it didn't follow the standard. – Lundin Feb 20 '12 at 10:59
  • 2
    @Lundin: My point is simply that you have a factually incorrect statement in your answer. A conforming C implementation may document and allow `void main(void)`. (And the behavior you describe doesn't make Turbo C non-conforming; defining `void main()` if the implementation doesn't document it has undefined behavior, but it doesn't require a diagnostic.) – Keith Thompson Feb 20 '12 at 18:09
  • 1
    Lundin, might I suggest that you consider removing the "A lot of incorrect answers, you should ignore them." - it makes you seem arrogant :-) The votes have already decided the best answer, you can probably leave it at that. – paxdiablo Mar 23 '12 at 13:43
  • @paxdiablo Indeed! Aren't all programmers arrogant, though? :) – Lundin Mar 23 '12 at 15:46
  • 1
    @Lundin: Only the very good ones and the very bad ones. 8-)} – Keith Thompson Aug 28 '12 at 08:10
7

Lundin is correct about C, but in C++ the wording is sufficiently distinct to make a difference:

[C++11: 3.6.1/1]: A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function.

[C++11: 3.6.1/2]: An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined [..]

The first bolded passage does not override or cancel out the second.

main returns int in C++, always.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 4
    *You can use `void`... except you can't.* – Bartek Banachewicz Feb 12 '13 at 11:17
  • 1
    And then 3.6.1/1 continues: "`Note: In a freestanding environment, start-up and termination is implementation-defined`". I don't know why the wording was changed in C++11, but this can only be reasonably interpreted as "freestanding implementations may declare main entirely as they please". It doesn't make sense for a program without any OS, or for the OS itself, to return an int. Who would they return the int to? – Lundin Feb 12 '13 at 12:12
  • @Lundin: Start-up and termination may be implementation-defined (so it may not even happen, or happen with a function named something other than `main`, or happen in some other way), but when there _is_ a global `main` function present, its return type is `int`. Always. This is very clear from the unambiguous wording. – Lightness Races in Orbit Feb 12 '13 at 12:21
  • @LightnessRacesinOrbit So in other words, freestanding C++ implementations should never implement main() then, since it is useless? Typically freestanding systems start up at some hardware-specified entry point ("boot sector" etc), from where fundamental hardware setup, as well as static initialization etc, everything that needs to run before main(). And from there, they call a `void main()`. You don't want to return to your entry point. If main had type int, then the calling convension may have to force a useless garbage int to be reserved on the stack, forever, which would just be stupid. – Lundin Feb 12 '13 at 12:38
  • @Lundin: If a freestanding implementation has an entrypoint function, and they call it `main`, and it's global, then it must have return type `int`. They are free to call it something else and have it be `void`. – Lightness Races in Orbit Feb 12 '13 at 13:29
  • @Lundin If I am not mistaken, the as-if rule would let the compiler ignore the return value in that case, and not reserve space on the stack for it, since it doesn't affect observable behavior. – Tim Seguine Dec 04 '13 at 21:25
  • @Tim But there's more in C++11. For example if you define main, you must not only return int, you must also allow argv argc, which also is complete and utter nonsense in freestanding environments. And that's normative text, no way around it. Apparently the C++ committee was hijacked by fanatic PC programmers during the release of C++11. The language is simply made less useful in embedded systems, because of all this dogmatic nonsense in 3.6.2. – Lundin Dec 05 '13 at 08:28
  • @Lundin The quoted snippet from the standard makes no such claim other than its return type being int and it specifically says that in freestanding environments(i.e. embedded) there need not even be a main function. – Tim Seguine Dec 05 '13 at 09:23
  • @Tim So read the whole of 3.6.2? Draft standards are available free of charge, Google C++11 draft. The C++11 main() function is adapted to PC programming, so it can no longer be used, simple as that. I guess it doesn't matter, since C is the completely dominant language in embedded systems anyhow. And the few unfortunate who insist on using C++ are already resigned/hardened/apathetic, since they have been swimming the flood of non-standard, non-compliant crap compilers on the C++ embedded market for the past 20 years or so. – Lundin Dec 05 '13 at 10:41
  • @Lundin I just read it. It requires that the two forms of main be available(but not required to be used by the programmer), one of which is a function accepting no arguments. It also allows for other signatures to be allowed by the compiler. returning int, as I already explained is a non-issue (even for embedded). If your compiler is forcing arguments and return values to take storage space in the startup code, then it is a problem with your compiler, not with the standard. – Tim Seguine Dec 05 '13 at 11:09
  • Feel free to continue to ignore everyone and the standard then. – Lightness Races in Orbit Dec 05 '13 at 12:35
5

The return type for main is determined by the implementation, not the programmer. Check your compiler documentation to see what the legal signatures are for main. Don't assume that void main() is one of them. In a hosted environment, main normally returns int. In a freestandaing environment, the entry point may not even be named main, but its return type will still be determined by the implementation, not the programmer.

John Bode
  • 119,563
  • 19
  • 122
  • 198
3

There are 3 situations:

  1. free standing implementation
  2. conforming hosted implementation with no extensions
  3. hosted implementation with extensions

In 1. there need not be a function named main at all. The implementation defines how a program starts.

In 2. a program starts executing at a function named main, defined with one of the following 2 'signatures': int main(void) or int main(int argc, char **argv)

In 3. a program starts executing at a function named main, defined as allowed by the implementation. This function must return int to be Standard conformant. For example: int main(int argc, char **argv, char **envp) or int main(wchar_t**). Note that programs which use these forms are not necessarily valid in all hosted implementations (and may become invalid for the original author if the implementation changes).

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
pmg
  • 106,608
  • 13
  • 126
  • 198
  • 1
    In case 3, `void main(void)` is still not valid. The standard allows hosted implementations to accept implementation-defined arguments to `main`, but not to accept different return types. – R.. GitHub STOP HELPING ICE Mar 14 '11 at 15:31
  • 1
    @R..: C++ requires `main` to return `int`; C allows implementation-defined forms to return other types. – Keith Thompson Feb 20 '12 at 10:09
  • Well the implementation may define any number of behaviors outside the standard as long as they don't conflict with the compiling or reporting of errors in conformant C programs. For example, gcc statement expressions `({...})` seem not to conflict with any requirements of the language, but I would hesitate to call a program using them "valid C" even if it were meant for a platform where gcc is usually used. – R.. GitHub STOP HELPING ICE Feb 20 '12 at 14:20
1

Originally, in the C language, there was no such type as void and therefore the function had to return int.

In practice, returning int allows you to run another process from your process (using fork and exec) and if you can get the return result from that process you will know whether it worked or not.

Azeem
  • 11,148
  • 4
  • 27
  • 40
CashCow
  • 30,981
  • 5
  • 61
  • 92
-1

Many compilers don't support void main(), therefore you should always use int main().

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • 8
    -1 This is wrong. If your program is an embedded system or an operative system, it will use void main(), which is perfectly fine by the C/C++ standard. See my answer further below. – Lundin Mar 14 '11 at 09:09
  • It's wrong not for that reason, but because what some compiler supports doesn't really have anything to do with it. – Lightness Races in Orbit Feb 12 '13 at 11:17