Function Declaration & Definition in C for main() - c

I researched & understood that the standard way of creating or writing a function in C is to:
function declaration - declare the function name, arguments, and return value
function definition - define the function with the actual code implementation
function call - call or invoke the function with the name and arguments
However I'm confused about the use of the function main(). Is it allowed in C to use main() in all blocks of code i.e. using main() in declaration, using main() in definition and using main() in call.
Help please my exam is next month & I'm confused.

The function main() in C is a special function name which indicates where your program is to start, the entry point in your program for the C source code you write. Part of the C Standard Runtime is a need to know the entry point for where the C program that you are writing starts from. This is indicated with the function name main().
First you must understand that a C compiler converts the C source code text into binary object files. These binary object files are then linked together with other binary object files to produce the actual executable program. One of these types of binary object files is library files which contain the binary code of one or more functions that were previously compiled and combined into a single file.
The C compiler comes with several library files that contains functionality which you will need to complete your executable program. One of these is the C Runtime for the compiler.
When your executable program starts up, it does not start at main(). It instead starts at a special place in the C Runtime which sets up the runtime environment for your executable and then calls the main() function you provide. The main() function is where your source code starts.
As part of the C compiler there are a also include files such as #include <stdio.h> and others. These include files contain declarations for the functions of the C Standard Library such as the printf() function.
So the main() function is declared for you in the C compiler however you have to provide the actual definition of the function.
Since main() is an external label there can only be one function called main() that you define. If you have more than one definition of main() then when the linker tries to link your binary object files together into an executable, it will see the multiple main() functions and issue an error because it will not know which one to use.
One way of thinking of this is: (1) the C compiler provides the declaration for main(), (2) you provide the definition for main() and (3) the C Runtime calls your function main() as part of starting up your program.
See also What is the difference between - 1) Preprocessor,linker, 2)Header file,library? Is my understanding correct?
Function definition for main()
The standard for C indicates two different declarations for main(): int main(int argc, char *argv[]) and int main(void) (see section 5.1.2.2.1 Program startup in draft ISO/IEC 9899:TC3). See also What does int argc, char *argv[] mean?. See also the various discussions in What should main() return in C and C++?.
Some C compilers may also provide other alternatives including a wide character interface such as int wmain(int argc, wchar_t *argv[]) (see WINMAIN and main() in C++ (Extended)). C++ compilers may allow int main(int argc, wchar_t *argv[]) because C++ allows function overloading which C does not. Microsoft C++ compilers have had a variety of main() alternatives depending on whether the target program was a console application or a GUI.
The normal way of using the return value of main() is to return a value of 0 if successful and a non-zero positive number if there was an error. This was the normal and accepted behavior from the original Unix environments where programs were run in a terminal window from a command line (see Wikipedia topic Bourne Shell and Wikipedia topic Bash as well as Returning value from called function in a shell script which contains some examples of scripts) and most programs were used with command shell scripts.
Some programs use the return value to indicate the results of a test of some kind. In those cases, the value returned by main() isn't either success or an error code but instead the return value indicates some condition that a script could test for as part of carrying out its purpose. For example a program that queries an air quality indication from a sensor may return three different values indicating Good, Fair, or Poor which a script then uses to do something such as turn on a ventilation system fan at a particular speed.
Here are a couple of examples of main() definitions:
// usage: mypgm pathname
// Open the specified file and do things with the file's contents.
//
// program expects a single command line argument specifying a file.
// if pathname is not specified then it's an error.
int main(int argc, char *argv[])
{
// there is always one argument as the first argument is always
// the program name. Any additional arguments added to the
// command line begin with the second argument.
// argv[0] -> program or command name
// argv[1] -> expecting a pathname to be specified
if (argc < 2) {
printf ("Filename not specified\n");
return 1; // return non-zero indicating an error
}
// source code to do stuff with the specified file
return 0; // return zero indicating no error
}
// usage: mypgm
//
// program does not expect any command line arguments and if any are
// specified the arguments are ignored.
//
int main (void)
{
// source code to do stuff
return 0;
}
// usage: mypgm
//
// program does not expect any command line arguments and if any are
// specified the arguments are ignored.
//
// the following definition also compiles.
int main ()
{
// source code to do stuff
return 0;
}

In C you may call main recursively. You shall not declare main without its definition.

C language standard 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.

In C, the compiler has to know a function's return type and parameter list (if any) before it can translate a function call.
A function definition also serves as its declaration; if you define the function before it is called within the same translation unit, then you do not need to write a separate declaration for it:
void foo ( void ) // definition, also serves as declaration
{
...
}
void bar( void )
{
...
foo(); // call
...
}
Since we define foo before it's called by bar, the compiler already knows foo's return type and parameter list, so we don't need another declaration before the call in bar. However, if we were to define foo after bar, or if foo were defined in a separate translation unit (source file), then we would need a separate declaration before the call in bar:
void bar( void )
{
void foo( void ); // declaration
...
foo( ); // call
}
void foo( void ) // definition
{
...
}
main is special in that there's typically no need for a separate declaration of it in your code; you don't normally call main explicitly. It's normally called by the run time environment, which already expects main to return an int and take either zero or two parameters, like so:
int main( void );
int main( int, char ** );
Implementations may provide additional signatures for main, which they must document.
About the only place I've seen anyone call main explicitly was in the IOCCC; I've never seen a valid use case for it in production code.

Related

What is the difference of all main functions? [duplicate]

This question already has answers here:
What are the valid signatures for C's main() function?
(5 answers)
Closed 3 years ago.
What is the difference between main, void main and int main in C? what does each one of them do?
Also what is return 0; used for? i know it somehow tells the OS that the program finished succesfully but what does that have to offer?
I would like to note that ive been working on C for a little more than a month so im not really experienced
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;10) or in some other implementation-defined manner.
10) 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.
C 2011 Online Draft
main() is equivalent to int main(void). Under earlier versions of the language, if you defined a function without an explicit return type, the compiler assumed it returned int. Also, if you define a function without any parameters, that means the function takes no parameters. Implicit typing is no longer allowed, and using prototype syntax allows you to catch errors in the number and types of arguments at compile time, so this form should no longer be used.
void main() is not standard, and should not be used unless your implementation explicitly documents it as a valid signature for main ("or in some other implementation-defined manner")1. Otherwise, using it results in undefined behavior, which may result in your code misbehaving on startup or exit. There are platforms where it runs with no apparent issues, but you shouldn't rely on that being true.
5.1.2.2.3 Program termination
1 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;11) 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.
11) In accordance with 6.2.4, the lifetimes of objects with automatic storage duration declared in main
will have ended in the former case, even where they would not have in the latter.
C programs return a status code to the runtime environment - on *nix and similar platforms, a return code of 0 indicates successful, normal program termination. stdlib.h defines the macros EXIT_SUCCESS and EXIT_FAILURE, which should be used instead of literal numeric values:
#include <stdlib.h>
...
int main( void )
{
...
if ( something_bad_happens )
return EXIT_FAILURE;
...
return EXIT_SUCCESS;
}
Even then, I wouldn't use it, because it's guaranteed to be non-portable.
The difference between them is that void main() is not a valid signature for the main function according to the standard. According to the standard, there are only two valid signatures, and those are:
int main(void)
int main(int argc, char *argv[])
A compiler may allow other signatures, but it is not required by the standard. One common non-standard signature is:
int main(int argc, char *argv[], char *env[])
The return statement simply returns an integer that can give information to the caller. If you're in a linux environment, you can inspect this value like this:
$ ./a.out
$ echo $?
In the bash shell, the variable $? contains the return value of the last exectuded command.
You can read more about main signatures and return values here: https://port70.net/~nsz/c/c11/n1570.html#5.1.2
int main is the only valid way to declare the main() function, the others are wrong. You can optionally specify parameters int main(int argc, char *argv[]), but the return type int is required.
The return value of the main() function is used to tell the calling application how the program ended. Returning 0 means that the program completed successfully, while non-zero values are used to indicate some kind of error. This is typically tested in shell scripts. You can also call the exit() function to end the program, its argument will be used as the exit status the same way (this allows terminating the program from inside functions).

void main() { } works perfectly without a header file. How can this happen ,where is the definition of main function written in C?

I wrote the following code:
void main() {
}
How can it run without any header files?
From the C Standard (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;10) or in some other implementation-defined manner.
Though some compilers as for example the compiler of MS VS support the declaration of the function main with the return type void nevertheless such a declaration is not a C standard declaration of the function main.
So as the implementation declares no prototype of the function main and if the function main does not call any other function then neither header is required.
You may just write
int main( void )
{
}
The return statement also may be omitted.
Pay attention to that it is the user who defines the function main. So in the presented program above there is a definition of the function main that does not contain any statement inside its body. The function does nothing and at once returns the control to the hosted environment.
Header files are just a language feature that provides means to organize code in different modules (translation units) or even in whole libraries. They are by no means mandatory to use.
The only thing that is mandatory in a C program is to have some manner of entry point to your program. On hosted systems (such as a PC with an OS), this entry point must be a function named main(). It can be declared in several ways. void main() is not guaranteed to work unless the compiler explicitly supports that form. The most portable and standardized format is:
int main (void)
{
return 0;
}
Now of course this program is not very exciting to run, as it does absolutely nothing. But it is perfectly valid.
There need not be any forward declaration of main(). For freestanding environments, the format of the entry point is completely implementation-defined. For hosted environments, the C standard explicitly says that "The implementation declares no prototype for this function." - implementation in this case meaning the compiler. In English it means that the main() function must simply work without any previous declaration present, as per language definition.
Details regarding the various allowed forms of main().
void is a built-in type, known by the compiler. main is the entry point for a program, while printf, as you have written, needs some prototype. If you write your own printf definition in your source code, it will compile without a header.
The only thing you have to do to compile a C program is specify a entry point, i.e. main.
The headers just provide other IO possibilities.
void printf()
{
}
int main()
{
printf();
}
If you are using printf in your code without a header, the compiler doesn't know to what type of entity you are refering.
If you provide an implementation of main, the compiler knows exactly what this is meant to be, you just specified it.

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.

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.

Difference between main(void) and main() in C [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 7 years ago.
Can anyone tell me the difference between int main() and int main(void)? Why do both of them work and what is the default argument to int main()?
No difference under ordinary circumstances. This is no 'default argument to main()', since it has no arguments at all.
Here's the un-ordinary circumstance. If you write your own call to main, then () will permit you to pass it any parameters you like, while (void) will force you to pass it none. Still, none of this matters in terms of the 99.99999999% case, which is main being invoked by the runtime to launch your program. The runtime neither knows nor cares if you write () or (void).
If you code the standard int main(int argc, char **argv) you will get your command-line parameters in there.
main() allows you to call main with any number of parameters. main(void) forces you to call main with no parameters. So:
main(foo, bar);
Is fine with main() but not with main(void) - the compiler generates an error.
Now if you're specifically asking about the program's entry point, it doesn't really make a difference; in either case, you won't have the arguments to the program (argc, argv, envp) available.
From a practical viewpoint, there's no real difference. With int main(void), you're explicitly stating that main takes no parameters, so you can't invoke it with any. With int main(), you're leaving open the possibility of invoking main with some parameters.
However, except in strange situations like code golf or intentionally obfuscated code, you don't invoke main anyway -- it's the entry point to the program, so it's automatically invoked by the startup code. The startup code will pass the command line arguments anyway, so your choices don't change how it's invoked, only whether you use or ignore the parameters that get passed.
The standard does specifically allow you to define main with or without parameters (§5.1.2.2.1/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;
Though it's outside the tags specified, in C++ the situation is slightly different. In C, a function declaration like:
int f();
specifies that f is a function returning an int, but gives no information about the number or type of parameters f might expect (this is included primarily for compatibility with old code -- at one time, this was the only way to declare a function in C). In C++, that same declaration explicitly declares f as a function that takes no parameters, so attempting to invoke f with one or more parameters cannot invoke this function (it must either invoke another overload or produce an error if no suitable overload is found).

Resources