1

When I was reaading ANSI C, I could Find Author Using Main Function in Various forms as follows

main(){}

void main(){}

int main(){return 0;}

main(void){}

void main(void){}

int main(void){return 0;}

These are the various forms I observed But couldn't understand

  1. what is term before "main"??
  2. what is that term called which is in () after main??/
  3. Why we have to use them and where ??
  4. Is Void a data type or return type?
  5. If that void in () brackets is the parameter that to be passes to function Why we should specify when we are passing nothing( As far as i know void is nothing) ???
  6. Do we have any other forms to write in C ???

Please don't get Irritated by my doubts am a beginner who started to learn very recently a few days back.. and please explain through some sample code if possible

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
AshrithGande
  • 351
  • 1
  • 10
  • 25
  • `void` means nothing, but it expresses explicit intention of nothing, as opposed to just neglecting to specify parameters. The compiler can syntax check against `void`. – lurker Feb 24 '14 at 19:59
  • @mbratch: This is not a duplicate of that question. It's very likely a duplicate of some other question. – Keith Thompson Feb 24 '14 at 20:03
  • 1
    @mbratch: `http://stackoverflow.com/q/5020362/827263` isn't about how to define `main`, it's about whether to write a separate prototype for `main`. – Keith Thompson Feb 24 '14 at 20:13
  • @KeithThompson indeed, I had already retracted my close vote. I read a bit to hastily. – lurker Feb 24 '14 at 20:15

3 Answers3

4

I'll quote from the C 2011 Specification:

Section 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[]) { /* ... */ }

or equivalent or in some other implementation-defined manner.

As to the additional questions:

  1. The term before main is the return type. So in this case, main has a return type of int.
  2. The stuff inside the parentheses are called function parameters. So main can be defined to have no parameters (the first valid version), or two parameters (the second valid version).
  3. The first version is used if you don't care about arguments to the program. The second version is used if you want to access those arguments. On a command line (on linux for example), you generally pass the program arguments as so:

    ./a.out argument_1 argument_2
    

    The arguments will be an array containing ["a.out", "argument_1", "argument_2"].

  4. The meaning of void is different in different contexts. If a function is defined with only a token of void in between the parentheses, that means that it takes no arguments.

    If, on the other hand, you were to define a new function, called foo, and you wanted it to return no value, you could do that like so:

    void foo() { ... }
    
  5. Both of the following statements are considered identical.

    void foo() { ... }
    void foo(void) { ... } 
    

    Section 6.9.1 Function Definitions

    If the declarator includes a parameter type list, the declaration of each parameter shall include an identifier, except for the special case of a parameter list consisting of a single parameter of type void, in which case there shall not be an identifier. No declaration list shall follow.

  6. The only one that comes to mind are the functions that can take a variable amount of arguments. This would include things like printf() and scanf(). However, I wouldn't worry about those until you fully understand regular functions.

Some additional thoughts on return values...

It's also worth mentioning that you are actually not necessarily allowed to return any integer from main(). In other int returning functions you can, but main() is a special case. Let's read:

Section 7.22.4.4 Paragraph 5

Finally, control is returned to the host environment. If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Therefore, the standard defines the following as valid return values from main():

  1. 0
  2. EXIT_SUCCESS
  3. EXIT_FAILURE
  4. Whatever your compiler also says is legal.

And to throw a small wrench in the works...

Implementations (that is, your compiler and operating system) are allowed to extend these rules. For example, Visual Studio 2010 also allows (for example):

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

And, to some arguable degree, that compiler allows return values in the range [0, 255].

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Regarding the return values, like the quoted part of the standard says other return values are _implementation-defined_. The following conclusion that “there are only 3 valid return values from `main()`” is therefore incorrect - any `int` value is valid, but the _meaning_ of values other than the three depends on the implementation. (This is [not the same as undefined behaviour](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior).) – Arkku Feb 24 '14 at 20:55
  • @Arkku: I've changed the answer slightly. Hopefully it is more clear now. – Bill Lynch Feb 24 '14 at 21:24
  • Regarding your 5th point, `void foo() { ... }` and `void foo(void) { ... }` are not equivalent. With the former, a call `foo(42)` has undefined behavior; with the latter, the same call is a constraint violation, requiring a diagnostic. – Keith Thompson May 08 '14 at 21:06
4

The forms that omit the return type are valid only in versions of C prior to the 1999 standard. In older versions of C, omitting the return type was equivalent to declaring an explicit return type of int. In C99 and later, omitting the return type is not permitted.

The forms that declare the return type as void are non-standard, and often a sign of a textbook written by someone who doesn't know the language very well. The only standard return type for main is int.

The forms that use empty parentheses () rather than (void) are obsolescent. The versions with the empty parentheses are old-style non-prototype definitions. It's still legal to use old-style definitions for functions in general; it's debatable whether it's permitted for main in particular. There's no good reason to use () rather than (void).

The permitted forms are:

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

and

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

or equivalent. The "or equivalent" means that you can use an equivalent typedef in place of int or char (but please don't), that you can spell the parameter names differently (but please don't), and that you can use char **argv rather than char *argv[] (char **argv is actually a more direct representation of the real parameter type).

The standard follows these two forms with the phrase "or in some other implementation-defined manner". Implementations may, but are not required to, support other forms, such as:

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

or even

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

Using such an alternate form is rarely necessary; sticking strictly to one of the two standard forms is good enough 99% of the time and makes your code more portable.

Of the forms in your question, only the last:

int main(void){return 0;}

is definitively valid. The third:

int main(){return 0;}

is probably valid, but you might as well add the void keyword and remove all doubt.

(An irrelevant aside: int main() { /* ... */ } is valid in C++, where the empty parentheses have a different meaning.)

(C uses (void) to indicate that a function has no parameters because the () syntax is already used for another purposes, to indicate that a function has an unspecified number and type of parameters. That usage of empty parentheses is obsolescent, and should be avoided in new code.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

The form that main may assume depends also from the kind of environment. In a hosted environment, where your program runs on top of an Operating System, main() must return int, and, as other people described here already, may have or may have not parameters. By the way if your program is not running in an hosted environment, but it runs in a hostless environment, so if it is a firmware for instance, it is allowed to have any return value. In this case the most common form is void main().

Note

When you compile a program on a hosted environment and you use the form void main() you don't get an error but you usually get a warning like:

 warning: return type of ‘main’ is not ‘int’

in this case the termination status returned to the host environment is unspecified, so for this reason I say that returning a int is a must. Microsoft VS permits the usage of void main() from Microsoft VS 2008, but because of the note above this form is not portable and I don't suggest using it.

Jekyll
  • 1,434
  • 11
  • 13