tags:

views:

580

answers:

6

people use void main() /*empty braces()*/
but have been tought to write void main(void)
any ideas about the diffrence?

+16  A: 

I'm not sure what the standards are nowadays, but in traditional ANSI C, using empty braces idicates that the function can take any number of arguments. Declaring a void parameter on the other hand indicates that the function only takes zero arguemnts. In this case (and many others), it really doesn't matter too much.

If you want to be strict though, it's probably best to define the void parameter. Of course, the main function can also be defined as int main(int argc, const char* argv[]) - which is perfectly valid, but often unnecessary if you don't care about arguments.

Noldorin
so i should write void main (void)?
fahad
IIRC, empty braces indicate any number of arguments at the declaration only. At the definition, you still have to spell them out (even if it's old-style: int main() int argc; char ***argv; { /* and so on */ } so the void in int main(void) is redundant.
Kaz Dragon
@fahad: Unless you're using a slightly non-standard C compiler like the one detly mentioned, you shouldn't. `main` returns `int`. If you declare it `void`, then whatever's left lying around in the relevant register will be considered your program's exit code, and that's not generally a good thing. As Nicholas said, if you're not using arguments, you could write `int main(void)` instead of the full declaration.
T.J. Crowder
@fahad: Yes, I would... T.J. Crowder makes a good clarification too.
Noldorin
@T.J. IIRC `void main()` is from original pre-ANSI C and the program was always returning 0 in the case.
Dummy00001
@Dummy00001: So, a long, long time ago (in computer terms). :-) More than 20 years.
T.J. Crowder
JeremyP
but: main is called from the startup code; if the startup code ignores return code, it makes sense (to stress this fact) to use `void main()`; and while `void main()` seems to say main can get arguments, but I am not interested in, `void main(void)` seems to say we expect that startup code does not pass arguments at all, which is slightly different. If I have an environment that expect not a return value, `int main()` would work the same (the return code is "naturally" ignored), but there's no stress on the fact that return code makes no meaning, so `void main()` is clearer. Isn't it?
ShinTakezou
@Dummy00001: UNIX programs have had return status since before the ANSI C standard of 1989.
ninjalj
A pretty important distinction between int main() and int main(void) is that the latter allows the compiler to do type-checking, helping to find bugs before it's too late.
ninjalj
@ShinTakezou: int main(void) and int main(int argc, char *argv[]) (and declarations with compatible types, i.e. char **argv instead of char *argv[] and so on) are portable, the rest are not.
ninjalj
@ninjalj define portable! you're totally wrong. The main prototype must match the prototype the startup code assumed. And `main(void)` meaning no arguments, does not change how startup code calls main, so it is more logical to me `main()`. If the startup code would have been compiled to be then linked, `int main(void)` would raise an __error__ (not a warning!), see the code I've added to my answer
ShinTakezou
I thought the *real* definition of `main` also had a third parameter for the environment, but almost everyone omits that. Am I wrong?
Donal Fellows
@Donal Fellows hi! No you're not wrong, I've seen that, but often is not used! -- (Here as OP Q was made, we should focus in "analysing" the diff between `()` and `(void)`, and as side effect, the validity of `void main` vs `int main`; `X main()` is "openminded" to any number of parameters, `X main(int argc, char **argv)` can accept more than 2 parameters anyway, while `X main(void)` explicitly says main has no parameters at all) -- side note: the caller is responsible for cleaning the stack, this is likely why `int main(void)` does no harm and the same for `int main()` or whatever
ShinTakezou
@Donal Fellows ; e.g. [here](http://www.opensource.apple.com/source/Csu/Csu-47/crt.c) main is defined as `extern int main( int argc, char **argv, char **envp, char **apple);`, not however as `int main(void)`
ShinTakezou
and in crt1.c (for MinGW) main is called like this: `nRet = main (_argc, _argv, environ);` ; again I __stress__ the fact that `int main()` is more correct for such a system and similar, since it says that there can be arguments, but we are not interested in, while `int main(void)` do not says we are not interested in arguments, it says main prototype does not accept arguments at all
ShinTakezou
@Donal Fellows: That one is implementation specific. You should use getenv() instead, if you want portability.
ninjalj
It's certainly a nasty mess. And I stick to the classic two-arg form, on the grounds that that's what everyone else uses and so it will be thoroughly tested.
Donal Fellows
@ninjalj I think we should separate standard definition of the language, and basic conventions (like the one about main... just since an entry point is likely needed), from the presence of what is called "standard library". I bet (but I can't check and I am not sure of this) the lack of the standard library does not make the compiler non-std-C-compliant (i.e. C std does not dictate the presence of std lib for every system). getenv is C89/99, POSIX and something else, so 1) it is not so widely portable 2) there are systems where we can use C standardized lang, but not getenv
ShinTakezou
@ShinTakezou: Have you ever seen a system which supports int main(int argc,char *argv[], char *envp[]) but not getenv()?
ninjalj
@ShinTakezou: The C standard defines freestanding and hosted conforming implementations. A freestanding conforming implementation doesn't need to provide complex types, or any library apart from <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h> and <stdint.h>. A freestanding conforming implementation can call whatever startup function it chooses, but it must document it.
ninjalj
@ninjalj it would be odd, since likely a getenv would just use char *envp[]; have you ever checked if all systems supporting int main(int argc, char **argv) have getenv? You insist on portability,but a lot of "themes" here can't be portable anyway,even if you stick to strict standards. And of course, the question "is it freestanding or hosted impl?" must always be done.To be back on OP topic, OP's `void main()` can't be intrinsically wrong; while writing `X main()` or `X main(void)` seems a subjective taste matter, rather than Decided By Standard (since current std allows both)
ShinTakezou
+2  A: 

There is no difference but usually main should return int. Some compilers will give you a warning (at least the GNU compiler - gcc):

$ cat x.c
void main(void){}

$ gcc x.c
x.c: In function `main':
x.c:1: warning: return type of 'main' is not `int'

As mentioned the prototype of main is (according to standard):

int main(int argc, const char* argv[])

Iulian Şerbănoiu
but have you tried cross compiling with gcc version or other compilers made for specific environments? it makes sense if the standard mandates the fact that `main` must be called with two arguments, and must returns an "exit value". I am not sure, but I think it does not (and if it does, there exists places where being not standard makes sense)
ShinTakezou
@ShinTakezou: What the standard mandates is that every compiler providing a "hosted" environment must support int main(void) and int main(int argc, char *argv[]). Compilers providing a hosted environment can support _also_ other declarations of main, and compilers providing a freestanding environment can call whatever function they choose at startup.
ninjalj
And so, I am right, the standard does not mandate it indeed: `int main()`, `int main(void)`, `int main(int argc, char **argv)`, `void main()`, `void main(void)` and so on are all possible, according to the environment. And since main is a name as others, startup code can call another one, just if it wants. So the answer to the OP's Q is more relaxed, or he has to specify the environment
ShinTakezou
+3  A: 

These prototypes of main() are both non-standard.

Precision on that question can be found on the comp.lang.c faq : http://c-faq.com/decl/main.html

EDIT: changed "wrong" to "non-standard" as the norm allows implementation-defined prototypes.

Gery
I disagree with something said in the faq. Main is called by startup code. If startup code ignores return code, it makes sense to have `void main()` or `void main(void)` as prototype for main.
ShinTakezou
@ShinTakezou: no, you're wrong. That's not portable.
ninjalj
They may make sense in certain circonstences, but they are not legal according to the norm of the langage (ISO/IEC 9899-1999).
Gery
@ShinTakezou: *only* if the compiler documentation **explicitly** says that `void main()` is supported. If not, then `main` should return `int`. There are platforms out there (Acorn is one, I believe) that will either fail to load the program or crash on program termination because the stack frame isn't set up correctly if `main` is typed `void`.
John Bode
@ninjalj - no you are wrong. standards do not force it to be what you say (see another commets done by another people about what std says about prototype for main). And who expects code for, say, GNU/Linux, to be portable on an obscure "controller"/embedded device?!
ShinTakezou
@Gery, it is no what another user says (I myself can't check the std): «C99 standard has this to say about main: "It shall be defined with a return type of int and with no parameters ... or with two parameters ... or in some other implementation-defined manner ". (section 5.1.2.2.1)» (by JeremyP)
ShinTakezou
@John Bode,it is what I've said, isn't it?The prototype for main should match the way main is called by the startup code.So `void main()`, `void main(void)`, `int main()`, `int main(void)` are all ok,depending on the environment.I thought the stack frame is not interested in the ret value,but it could be in the case `main(void)` against `main()`:the stack frame is set up for the args, normally;but of course there can exist cases where return value is put in the stack,and if this is the Acorn case void and int as return type makes a difference,you're right;I'd be interested in refs anyway
ShinTakezou
@John Bode, with "it is what I've said" I referred to my answers, mainly.
ShinTakezou
@ShinTakezou: "Implementation-defined" means that the implementation must explicitly document the allowable signatures for `main` (assuming a hosted implementation, which is what most of us are probably working on). If the implementation explicitly says that `void main()` is a valid signature, then it's okay to use it. Otherwise it is not. You cannot arbitrarily decide what the interface for `main` should be based on how you think the startup code works. The implementation owns the interface for `main`, not the programmer.
John Bode
@John Bode, And so, what's the point if not to ask the OP which enviroment he intends to use or consider `void main()` possible, i.e. right, in its own context? (unspecified) Have I arbitrarily dediced what?! The signature is specified according to what the startup code does, so «If startup code ignores return code, it makes sense to have void main() or void main(void) as prototype for main». Notice the __if__
ShinTakezou
A: 

main is a function, as other function. Almost. Anyway, being a function, it is called by some other code (a start up code). Usually (read: almost always) int main() is the correct one, but indeed what is the real correct one depends on the platform you are working it. Since, as said, main function could be called by a startup code that pass in no arguments at all, and that expect no a return value in a specific register (so that void main(void) is correct).

The int main() is correct since normally start up code expect a return value, and pass in two arguments. By saying int main(void) you are saying main takes no argument at all, that is false in most cases. With () you say there are arguments (one, two, three, you don't care), but you are not interested in them, so you are not interested in saying what they are and which type they are.

As I can see in codes, the most used prototype for "normal" environments (no embedded device or other "strange" environments where main can be called differently) is int main() when you disregard the passed int argc, char **argv arguments. (GCC complain since we are using a version for gcc suitable for the enviroment; test it with cross GCC version for one of the environment where startup code does not pass any arguments and expect no a return value)

edit

Just to be kind to skeptical persons; on the an environment where the main function is called, with two arguments, the following

int func()
{
  return 0;
}

int func2(void)
{
  return 1;
}

int main(void)
{
  int a;
  a = func(a, a); /* A */
  a = func2(a);   /* B */
  return 0;
}

says no error for A, while for B says too many arguments to function ‘func2’, compiled with gcc -std=c99 -pedantic. Changing int main(void) into int main() makes no difference, and no warnings.

On other evironments (I can't do practical tests now), void main(void) is ok, while in this case it raises a warning. The warning is not because of standard alone, but only since in the environment in use the prototype for main does not match. Standard seems to allow any other "configuration" for main.

In the OP case, considerering the "normal" enviroment (O.S. like GNU/Linux e.g.), where two args are passed to the main, and a return value is expected, the int main() is preferable (arguments are pushed on the stack by the startup code whether you say int main(void) or not, so int main() to me make more sense)

edit

One more note, always for skeptical person. As already proved, B raises an error, since I've said that it is int func2(void) but I call it passing an argument. Then, let us suppose we can compile the startup code and link it, as any other code. Somewhere, it will call the main, in a way like

retval = main(argc, argv);

If we used int main(void), the compiler will stop, giving an error, since startup code (in this environment) is trying to call main with two arguments. If we use int main() nothing happens and the code gets compiled correctly.

So, int main() is superior to int main(void) (in environment where we expect two arguments to main possible)

edit

More likely the call is like

retval = main(_argc, _argv, environ);

on many systems, but this does not change the previous speech.

ShinTakezou
int main() is a historical accident, and should have been deprecated since 1989.
ninjalj
as someone else's answer says,`function()` means, I don't care of the argumets,if any (any num of arguments).While `void` specifies that the caller _passes_ __no__ args,and you know that (and if somewhere it does, an error occurs).In another comment, someone reported a piece of C99 std,where to me it is clear that `int main()` is reasonable. And: do you write more often `int function() { ... }` or `int function(void) { ... }`? And if we analyse the vast amount of code out there, we find more often `int func(void) ..` or `int func() ..`? moreover if it is part of the std, `-std=c99 -pedantic` >
ShinTakezou
@ninjalj ...> `-std=c99 -pedantic` options should say something, and it does not. So, show us where it is said that `int main()` is deprecated.
ShinTakezou
Notice I wrote "should have been", not "has been". Of course, it was considered (correctly, IMNSHO) way more important to be compatible with legacy code than to force type-checking. I still would recommend using gcc's -Wstrict-prototypes -Wmissing-prototypes when compiling C code.
ninjalj
no warnings even with `-Wall`. I repeated my points in [another answer](http://stackoverflow.com/questions/3144316/when-main-is-defined-without-parameters-will-argc-and-argv-still-be-present-on-t/3160188#3160188). Why should have been deprecated? I think it makes sense. Expecially for main, where `int main()` means "I won't use passed in args", while `int main(void)` means "main gets no arguments"; they are different sentences and it is what I am focusing on towards my idea the `int main()` should be used where argc and argv are passed (since they are passed anyway)
ShinTakezou
the fact that `-Wstrict-prototypes` raises warnings does not mean anything, otherwise the warning would be selected implicitly by the `-pedantic` and `-std=c99` options. Moreover, we can activate a lot of _warnings_ that has nothing to do with standards (they could have something to do with "best practices", but I've explained why `int main()` is not a bad practice, when main is called passing two (or more) arguments, as it happens on the system we are dealing with most of the time)
ShinTakezou
__Moreover__ I am doing tests for other reasons and had to try compiling code with `-ansi -pendantic`... on that code, obtained: `warning: ISO C90 forbids mixed declarations and code`. This makes me think, if `int main()` would be against standard, gcc would say something like `ISO C99 forbids...`... So, provided a specific system, it is a matter of taste if using `int main()` or not. I've explained why I prefer `int main()` when I expect indeed `int main(int argc, char **argv)`. None has done, the vast majority misinterpreted the std, and mine is the only A wth -1! Funny
ShinTakezou
Funny again! This lost and forgotten answer gets another -1 because my current "exposition" in another "standard compliance" related question! This means that people thinking I am strongly wrong, digged my answers to pick other wrong (to their judgement, at least, this is honesty!) and downvote it :) - at least this is what it seems to be happened if I don't believe in coincidences!
ShinTakezou
+8  A: 

From the C99 standard:

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.

Cf: When main is defined without parameters, will argc and argv still be present on the stack?

EDIT: I fixed the link. Thanks Shin.

Tim Schaeffer
«or in some other implementation-defined manner.» since OP does not specify the implementation,his `void main` is ok.While it is wrong that the implementation declares no prototype.It is true that it does not declare a __"publicly available"__ prototype,but I digged startup codes,and when written in C itself,they __do__ declare the prototype(of course).Your link gives 404;anyway the answer is __yes__ if the startup code does so;and so when you mean `int main(int argc, char **argv)` but you are not interested in args, `int main()` is more logical.
ShinTakezou
A lot of people misinterpret the last part: _or in some other implementation-defined manner_. I strongly recommend reading Stroustrup to get this clear: See http://www2.research.att.com/~bs/bs_faq2.html#void-main
dirkgently
A: 

Actually empty braces in C represents void. Thats why you may or may not use this keyword in main function. But in some case types is mandatory. If you do not want anything there then you must have to give void keyword there. Example: User define functions.

chanchal1987