Why don't we use (void) in main? - c

People use void main() /*empty parens ()*/
I have been taught to write void main(void)
Any ideas what the difference is?

I'm not sure what the standards are nowadays, but in traditional ANSI C, using empty parentheses indicates that the function can take any number of arguments. Declaring a void parameter on the other hand indicates that the function only takes zero arguments. 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.

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.
When main is defined without parameters, will argc and argv still be present on the stack?

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.

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[])

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.
final edit
Did anyone find that when building a command line tool (i.e. on systems where int argc, char ** makes sense) with int main(void), the chosen compiler/linker links a startup code where the main is called without arguments (whatever the calling conventions are), and instead when building with int main(int argc, char **argv) the startup code is different and in fact calls the main with those two arguments (even if the main itself doesn't use them)?

Related

A few questions about functions and arguments

So I'm learning about functions in a book.
It says we need to prototype or declare functions so the compiler can understand if they are correctly called or not.
But why does the main function works without a prototype?
I used to write main functions in my learning process like this:
int main(void)
So it will not get any argument because of (void)
I tried to run my program with argument for example > ./a.out 2
int main(int y){
printf("%s %d\n","y is",y);
}
When I run it normally y is 1, when run it with > ./a.out 1 y is 2, when there is more than one argument it increases by one. So it's not the right way but what causes this?
Declaring y as char says nothing so my guess is it works like the return value of scanf(). It returns number of successful inputs.
A function must be either declared (i.e. a prototype) or defined before it is called. The main function is different from other functions in that it's called by the program startup code and not some other function.
There are however restrictions on what the signature of main can be. On a regular hosted implementation, the C standard says it can be either:
int main(void)
Or:
int main(int argc, char **argv)
The latter case is used to read command line arguments. argc contains the number of arguments passes, including the program name. argv contains the actual arguments as an array of char *.
Many systems also support:
int main(int argc, char **argv, char **envp)
Where envp contains the environment variables known to the program.
The prototype you're using: int main(int y) is not supported in any implementation I'm aware of, so attempting to use such a prototype for main invokes undefined behavior.
When I run it normally y is 1, when run it with > ./a.out 1 y is 2, when there is more than one argument it increases by one. So it's not the right way but what causes this?
The standard entry for program startup kind of answers both your questions:
N1570 § 5.1.2.2.1 Program startup
1 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[]) { /* ... */ }
[...]
As dbush already stated in the accepted answer these are the only two main implementations allowed by the standard.
The standard leaves the responsability of dealing with undefined constructs opened and imposes no requirements for what the behavior should be, a given implementation may deal with the situation in any way it considers appropriate, this is known as undefined behavior.
What seems to be happening is that your compiler is assuming that y is argc, which is allowed (as you can see in the second snippet of highlighted citation above), and argc stores the number of arguments in the command line, which is consistent with the results you're having, but again, this behavior may differ in different compilers, systems or even versions of the same compiler.

What are the differences between: main(){}, int main(){} and int main(void){} [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Why is the type of the main function in C and c++ left to the user to define? [duplicate]
(6 answers)
Closed 9 years ago.
I am currently learning C and I have written many small programs. However, I have noticed that the main function could start as
main()
{
//code
}
or
int main()
{
//code
return 0;
}
or
int main(void)
{
//code
return 0;
}
Which option should I use? Thanks!
For Standard C
For a hosted environment (that's the normal one), the C99 standard
says:
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;9) or in some other implementation-defined manner.
9) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char **argv, and
so on.
This (is valid in C89) main() implicitly meant (previously) int main(void). However the default return type rule has been abandoned in C99. Also:
main() means - a function main taking an unspecified number of arguments of.
main(void) means "a function main taking no arguments.
Your first example uses a feature inherited from the outdated dialect of C which predated the first ANSI(1989) and ISO(1990) standard: namely, that you can write a function which doesn't specify its return type, and in that case the type defaults to int.
In early C, the void keyword and associated type did not exist. When programmers wanted to write procedures ("functions that have a side effect, but do not return anything"), they simulated it using this feature. They wrote a function without any keyword specifying the return type. They allowed the function to execute to it last statement without returning a value (or alternatively, they used return; to exit from the middle without supplying a value), and they wrote the calls to the function such that those calls did not try to use the return value:
parse_input() /* similar to a procedure in Pascal, but fake! */
{
/* ... */
if (condition())
return; /* no value */
/* ... */
/* fall off end here */
}
int main()
{
parse_input(); /* no return value extracted, everything cool! */
return 0;
}
Unfortunately, some programmers also started not caring about the termination status of a program and writing main itself in this procedure style:
main()
{
/* do something */
/* fall off the end without returning a value */
}
(A mixed style also existed: omitting the int declarator but returning an integer value.)
These programs failing to return a value had an indeterminate termination status. To the operating system, their execution could look successful or failed. Woe to the script writer who tried to depend on the termination status of such a program!
Then things took a turn for the worse. C++ came along and introduced void, and it was adopted into C. With the void keyword in C++, one could declare a function that actually returns nothing (and make it an error to have a return; statement in any other kind of function). The dummy programmers who used to write main with no return type got dumber, and started sticking this new-fangled, fresh-out-of-C++ void in front:
void main() /* yikes! */
{
/* do something */
/* fall off the end without returning a value */
}
By this time they had forgotten that when they wrote main(), it actually meant int main(), which made the function have a compatible type with the startup call invoked by the environment (except for the matter of neglecting to return a value). Now they actually had a different function type from the expected one, which might not even be successfully called!
Where things stand now is that in C++ and in the latest C++ standard, main is still required to return an int. But both languages make a concession for the original dummy programmers: you can let execution "fall off" the end of main and the behavior is as if return 0; had been executed there. So this trivial program now has a successful termination status as of C99 and, I think, C++98 (or possibly earlier):
int main()
{
}
But neither language makes a concession for the second-generation dumber programmers (and everyone else who read the C books that those programmers wrote in the 1980's and since). That is, void is not a valid return declarator for main (except where it is documented by platforms as being accepted, and that applies to those platforms only, not to the portable language).
Oh, and allowance for the missing declarator was removed from C in C99, so main() { } is no longer correct in new dialects of C, and isn't valid C++. Incidentally, C++ does have such a syntax elsewhere: namely, class constructors and destructors are required not to have a return type specifier.
Okay, now about () versus (void). Recall that C++ introduced void. Furthermore, though C++ introduced void, it did not introduce the (void) argument syntax. C++ being more rigidly typed introduced prototype declarations, and banished the concept of an unprototyped function. C++ changed the meaning of the () C syntax to give it the power to declare. In C++, int func(); declares a function with no arguments, whereas in C, int func(); doesn't do such a thing: it declares a function about which we do not know the argument information. When C adopted void, the committee had an ugly idea: why don't we use the syntax (void) to declare a function with no arguments and then the () syntax can stay backward compatible with the loosey-goosey legacy behavior pandering to typeless programming.
You can guess what happened next: the C++ people looked at this (void) hack, threw up their arms and copied it into C++ for the sake of cross-language compatibility. Which in hindsight is amazing when you look at how the languages have diverged today and basically no longer care about compatibility to that extent. So (void) unambiguosly means "declare as having no arguments", in both C and C++. But using it in C++ code that is obviously pure C++ never intended to be C is ugly, and poor style: for instance, on class member functions! It doesn't make much sense to write things like class Foo { public: Foo(void); virtual ~Foo(void) /*...*/ };
Of course, when you define a function like int main() { ... }, the function which is defined has no arguments, regardless of which language it is in. The difference is in what declaration info is introduced into the scope. In C we can have the absurd situation that a function can be fully defined, and yet not declared, in the same unit of program text!
When we write main, usually it is not called from within the program, and so it doesn't matter what the definition declares. (In C++, main must not be called from the program; in C it can be). So it is immaterial whether you write int main() or int main(void), regardless of whether you're using C or C++. The thing which calls main does not see any declaration of it (that you write in your program, anyway).
So just keep in mind that if you write:
int main() /* rather than main(void) */
{
}
then although it is perfect C++ and correct C, as C it has a slight stylistic blemish: you're writing an old-style pre-ANSI-C function that doesn't serve as a prototype. Though it doesn't functionally matter in the case of main, you may get a warning if you use some compilers in a certain way. For instance, GCC, with the -Wstrict-prototypes option:
test.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
Because -Wstrict-prototypes is a darn useful warning to turn on when programming in C, for improved type safety, (along with -Wmissing-prototypes), and we strive to eliminate warnings from our compile jobs, it behooves us to write:
int main(void) /* modern C definition which prototypes the function */
{
}
which will make that diagnostic go away.
If you want main to accept arguments, then it is int main(int argc, char **argv) where the parameter names are up to you.
In C++, you can omit parameter names, so this definition is possible, which serves nicely in the place of main().
int main(int, char **) // both arguments ignored: C++ only
{
}
Since the argument vector is null-pointer-terminated, you don't need argc, and C++ lets us express that without introducing an unused variable:
#include <cstdio>
int main(int, char **argv) // omitted param name: C++ only
{
// dump the arguments
while (*argv)
std::puts(*argv++);
}
first :
declares a function main - with no input parameters. Although main should have returns ( your compiler will take care of this )
2nd/3rd:
Declare a function main which returns an int and takes in no input parameters
You should use 3rd format. Rather this is the best way:
int main(int argc, char *argv[]){
return 0;
}
You should use 1 one of these 4 choices:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);
where it's conventional to use the names argc and argv; you can change them but don't.
Take care never to use void main(void); which is too-often seen in production code.
By default main function returns an integer type, hence its "int main()" or you can give simply "main()"
"main(void)" is same as "main()", it tells the compiler that main function has no arguments.
In case if you want to pass arguments via main function:
int main(int argc, char *argv[]){
return 0;
}
main(){}
The above line give you an error. The default return type of any function in c is int. As the above code return nothing it gives you an error.
int main(){
//body
return 0;
}
In above code it fulfill all requirement so the above code will run.In above code we pass no argument in the function. So this function can take global and local variables to process.
int main(void)
{
//code
return 0;
}
In above code we pass no argument in the function. But specifying void tells the compiler that it does not take any argument. void is the default datatype of argument that signifies no input.

main() function defined without return type gives warning

This is my program:
main()
{
printf("hello world\n");
}
I get this warning when compiling it:
function should return a value
When changing main() to void main(), the warning disappears.
Why is that so?
There are few things which you should take note of :
The int is the main() function's return type. That means that the kind of value main() can
return is an integer.
main( ) was tolerated by the C90 compilers but not by C99 compilers which means its not a part of C99 standard anymore , so don't do this.
void main() is not a standard form ,some compilers allow this, but none of the standards have ever listed it as an option. Therefore,
compilers don't have to accept this form, and several don't. Again, stick to the standard form,
and you won't run into problems if you move a program from one compiler to another.
And one last thing , instead of writing main like this :
int main() // here you are being silent about passing arguments to main , meaning it may or may not take arguments
write like this :
int main(void)// this specifies there are no arguments taken by main
You might wanna look at the C99 standard for further details.
Quick summary: If you don't want to use command-line arguments, you should write:
int main(void) {
/* body of main function */
}
If you do:
int main(int argc, char *argv[]) {
/* ... */
}
These are the only portable ways to define the main function.
You should probably have a return 0; at the end, though it's not strictly necessary. Returning 0 indicates successful execution. There are ways to indicate that execution failed; I won't get into that here.
There's some history behind this. The rules for a valid definition of the main function have changed a bit across different releases of the C standard.
Before the introduction of the first official standard for C in 1989, the most common form was:
main()
{
/* ... */
}
Or, if you wanted to use command-line arguments:
main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
/* ... */
}
There was no way to define a function that didn't return a value. If you didn't specify a return type, it defaulted to int.
The 1989 ANSI C standard (which was republished with editorial changes as the 1990 ISO C standard) introduced prototypes, function declarations and definitions that specify the parameter types. There are two equally valid definitions for main. You can use one or the other depending on whether you need to use command line arguments:
int main(void) {
/* ... */
}
or
int main(int argc, char *argv[]) {
/* ... */
}
(char *argv[] can also be written as char **argv. This rule applies only to parameter definitions.)
A given compiler may or may not choose to permit other forms. For example, some compilers support a third parameter envp.
Somehow, some authors have gotten the idea that void main() or void main(void) is valid. It can be valid for some particular compiler, but only if that compiler explicitly supports it. It's not portable. The odd thing about this is that the same standard that first introduced the void keyword simultaneously established the rule that main's return type is int.
void main() is useful as an indicator that the author of the book you're reading doesn't know the C language very well, and that you should find another book.
The story is different for "freestanding" (embedded) systems. For such systems, the program's entry point is entirely implementation-defined, and might not even be called main. Defining it as void main(void) may well be valid for such systems.
The 1999 ISO C standard dropped the "implicit int" rule. Taking advantage of that rule was probably never a good idea in the first place. As of ISO C 1990, you could legally use:
main(void) { /* ... */ }
because it was equivalent to:
int main(void) { /* ... */ }
As of the 1999 standard, the int is mandatory.
The 1999 standard also added a special-case rule: reaching the closing } of the main function is equivalent to executing return 0;. It's still not a bad idea to add the explicit return 0;, especially if your code might be compiled with a pre-C99 compiler.
The 2011 ISO C standard didn't make any changes in this area.
The difference between int main() and int main(void) is that the latter explicitly says that main takes no arguments; the former doesn't specify how many arguments it takes. Use the int main(void) form. There have been debates about whether int main() is even legal.
You can likely get away with writing void main(), since it's an error that compilers are not actually required to diagnose (it's undefined behavior unless the implementation documents it).
The bottom line: The proper definition of main has a long and varied history, and there are a lot of variant forms you can probably get away with using. But unless you're programming for an embedded system, there is no point in using anything other than one of the two officially valid forms:
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }
c automatically implies the datatype int to functions with no declared datatype. So as far as the compiler is concerned the above is:
int main()
{
printf("hello world\n");
}
This expects that you would return an integer at the end of it with a return statement. If you explicitly specify it as void main() you are telling the compiler that the function does not have a return value, hence no warning.
The reason that this is not an error is that if not specified, main() will return 0; at the end of execution. However the compiler is still giving you a warning that this is happening.
Best practice is to use int main() and then return 0 at the end of your program execution like this.
int main()
{
printf("hello world\n");
return 0;
}
See: this question for more information.
You got the warning because you didn't specify the return type of main.
You should always use int main, and return an int number, usually 0 for success.
int main()
{
printf("hello world\n");
return 0; //you can omit this since C99
}
Using void main on a hosted environment(normally we are, if not, the following doesn't have to be true) leads to undefined behavior, even though it works in some compilers, never use it.
The standard says main has two kinds of prototype, both returns int:
C11 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;10) or in some other implementation-defined manner.
write
return 0 ;
at the last line.

Difference between int main() and int main(void)?

What does the following mean :
int main(void) {...}
VS
int main() {...}
?
I think that int main() {...} means that main doesn't receive any parameters (from command line) , however:
int main(int argc, char *argv[])
does.
But, what does int main(void) {...} mean? And, what does void stand for ?
I've looked here but it's somehow a different question .
In C++, there is no difference.
In C, the difference is questionable. Some love to argue that the latter version (the one without void) is technically just a common implementation extension and not guaranteed to work by the standard because of the wording in the standard. However, the standard clearly states that in a function definition an empty set of parameters has a well-defined behaviour: that the function does not take any parameters. Thus such a definition for main matches the following description in the standard:
It [main] shall be defined with a return type of int and with no parameters.
There is, however, a noticeable difference between the two: namely, the version without void fails to provide a correct prototype for the function:
// this is OK.
int main()
{
if (0) main(42);
}
// this requires a diagnostic to be shown during compiling
int main(void)
{
if (0) main(42);
}
Oh, and just to be complete: the void has the following meaning in all function declarators:
(6.7.6.3p10) The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.
First of all, there is a difference of what is allowed for hosted systems and freestanding systems, as shown here.
For hosted systems, 5.1.2.2.1 Program startup applies:
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)
... (more text follows regarding argv/argc etc styles).
The interesting part is "with no parameters". int main() and int main (void) are currently equivalent, since they are both function declarators and have no parameters. The following applies (6.7.6.3 ):
10 The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.
/--/
14 An identifier list declares only the identifiers of the parameters of the function. An empty
list in a function declarator that is part of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied.145)
Emphasis mine, the bold text is what applies to int main(). There is also note 145) at the end of the text, which says "See ‘‘future language directions’’ (6.11.6)":
6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.
And here is the difference. Being a function declarator, int main() is bad style because of the above, since it is not guaranteed to work in the next version of the C standard. It is flagged as an obsolescent feature in C11.
You should therefore always use int main (void) on a hosted system and never int main(), even if the two forms are, for now, equivalent.
In C++ both forms are completely equivalent, but there int main() is the preferred style for subjective, cosmetic reasons (Bjarne Stroustrup says so... which is probably quite a bad rationale for explaining why you do something in a particular way).
In C, in a prototype (not in C++ though) an empty argument list means that the function could take any arguments (in the definition of a function, it means no arguments). In C++, an empty parameter list means no arguments. In C, to get no arguments, you have to use void. See this question for a better explanation.
In C++ having a function foo(void) and foo() is the same thing. However, in C it's different: foo(void) is a function that has no arguments, while foo() is a function with unspecified arguments.
In C++, there is no difference, both are same.
Both definitions work in C also, but the second definition with void is considered technically better as it clearly specifies that main can only be called without any parameter.
In C, if a function signature doesn’t specify any argument, it means that the function can be called with any number of parameters or without any parameters. For example, try to compile and run following two C programs (remember to save your files as .c).
In C++, there is no difference between the two, and int main() is a legal signature and return type for main.
I know the thread is old but this question was bothering me for a while a few years ago so I wanted to throw in my half a cent(if that).
I always treat C functions as if they have fixed amount of arguments regardless of context, unless they use va_args. That is, I trust main to ALWAYS have the prototype:
int main(int argc, char **argv).
even if no arguments are passed, the function has these arguments on the stack because the main function does not have function overloading.
C does have the ability to have primitive overloading through just pretending the argument is not there. In which case, the argument is still passed and is on the stack but you never access it, so it merely reduces size of the source code.
Saying int main() simply means that I know that the function may have parameters, but I am not using them, so I write int main().
Saying int main(void) says that main CERTAINLY has no arguments, and implies that there are two different function prototypes:
int main(void);
int main(int argc, char **argv);
Since C has no function overloading, this is somewhat misleading to me, and I distrust code that has main(void) in it. I would not if main NEVER took any parameters, in which case main(void) would be completely OK.
NOTE: In some implementations, there are more parameters in main than argc and argv, such as env, but this does not bother me because I know that I do not explicitly say that those are the only two parameters, but those are the minimal parameters and it's okay to have more, but not less. This is in contrast to downright saying int main(void) which yells at me as THIS FUNCTION HAS NO PARAMETERS, which isn't true, since it does, they are just omitted.
Here is my basis code:
/* sample.c - build into sample. */
#include <stdio.h>
int main(void)
{
int _argc = *((int *)2686800);
char ***_pargv = (char ***)2686804;
int i;
for (i = 1; i < _argc; ++i) {
printf("%s ", (*_pargv)[i]);
}
return 0;
}
./sample I clearly have arguments
The function clearly has arguments passed to it, despite going out of the way to explicitly say that it doesn't by typing void into the function prototype.
As eq- says above:
(6.7.6.3p10) The special case of an unnamed parameter of type void as the
only item in the list specifies that the function has no parameters.
Thus saying that the function has void as an argument but actually having arguments on the stack is a contradiction.
My point is that arguments are still there, so explicitly asserting that main is void of arguments is dishonest. The honest way would be to say int main(), which claims nothing about how many parameters it has, only how many parameters you are care about.
NOTE2: The _argc, _pargv are system dependent, to find your values you must find them out by running this program:
/* findargs.c */
#include <stdio.h>
int main(int argc, char **argv)
{
printf("address of argc is %u.\n", &argc);
printf("address of argv is %u.\n", &argv);
return 0;
}
These values should remain correct for your specific system.
In C++, there is no difference between int main() and int main(void).
But in C they are little bit different.
int main() indicates that the main function can be called with any number of parameters or without any parameter. On the other hand, int main(void) indicates that the main function will be called without any parameter
#include <stdio.h>
int main()
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
Output: 4 3 2 1
#include <stdio.h>
int main(void)
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
It will show error. Because, in int main(void) parameter is void but in the program we have taken main(10) (which defines some value, not void)
Technically, if your host is partially POSIX compliant, then you have
int main(); // this legacy is always used by the run time library
int main(int argc); // illegal by compiler
int main(int argc, char** argv); // required by C standards
int main(int argc, char** argv, char** envp); // required by POSIX standard
If you have a Mac, there is also this
int main(int argc, char** argv, char** envp, char** apple); // required by Macintosh standard
Your host will send all the arguments, so a host will always send argc, argv, and envp (and apple if you are using an Apple product), but the programmer could have their main declared as taking void. The implicit function pointer typecast is technically an undefined behavior.
To prevent the typecast undefined behavior, int main() is a neutral form that means it could take any fixed number of arguments using canonical type promotion (int or larger, and double or larger) and int main(int argc, ...) means it could take any variable number of arguments also with canonical type promotion. In other words, the form return_type function_name() is an exception to undefined behavior.
In C++:
ㅤㅤint main() and int main(void) are the same in C++. They both take 0 and only 0 parameters.
In C:
ㅤㅤint main() takes as many arguments as you want. The function just won't use them. intㅤㅤㅤ main(void) makes it so passing an argument will create an error and make it impossible to ㅤㅤpass arguments.
ㅤ

Declare main prototype

Is there any reason why I never see main's prototype declared in C programs, ie:
int main(int argc, char* argv[]);
int main(int argc, char* argv[])
{
return 0;
}
Always seemed inconsistent..
C language standard, draft n1256:
5.1.2.2.1 Program startup
1 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;9) or in some other implementation-defined manner.
Emphasis mine.
Declaring the prototype means that you want to call it elsewhere, which makes no sense for main() function.
There's no need for a prototype, since main shouldn't be called by other procedures (and in C++ calling main is actually forbidden).
The simple reason being that the control always first go to main.Thus it is automatically located by the compiler thus giving its prototype is redundant and is of no use.
Also we use prototype when call to a function is made prior to its definition.Thus looking at the function prototype compiler can decide whether call is legitimate or not.But in case of main we are accustomed to provide its definition along with its declaration (which is logically correct also)thus no need of prototype.
Even when we make our c programs organized into multiple files there is no need for prototype of main.
The original purpose of prototypes was to support forward references to functions that could be processed by single pass compilers.
In other words, if you have something like this:
void function_A(){
printf( "%d", function_B( 5 ) );
}
int function_B( int x ){
return x * 2;
}
function_B is called before it is defined. This will create problems for simple compilers. To avoid these problems, putting prototypes at the beginning of the file, ensures that the compiler knows about all the functions in the file ahead of time, so forward references are not a problem to type check.
Since all the valid forms of the main function are known to the compiler beforehand, it is unnecessary to create a prototype, because the compiler can type check a forward reference to main() without it.

Resources