Standard C main Function Signatures and Return Types
The ISO C standard strictly defines how a program entry point must be
declared in a hosted environment, specifically restricting the return
type and parameter signatures of the main function. While
compilers often accept non-standard variations without throwing fatal
errors, adhering to standard-conforming signatures ensures program
portability, predictable stack management, and correct exit code
handling across different platforms.
The Standard Return Type
In a hosted environment (the typical operating system environment
where C programs run), the standard-conforming return type for
main is always int.
Using void as a return type (i.e.,
void main()) is non-conforming under ISO C standards.
Operating systems expect an integer termination status upon program
completion. Returning an integer allows the runtime to pass an exit code
back to the parent process or shell (such as 0 or
EXIT_SUCCESS for successful execution, and non-zero values
or EXIT_FAILURE for errors). In C99 and later standards,
reaching the closing brace } of main without
an explicit return statement implicitly returns
0.
Conforming Parameter Signatures
The ISO C specification (from C89 through C23) explicitly mandates
two primary signatures for main in a hosted
environment:
1. No Parameters
int main(void)This signature specifies that the program does not accept
command-line arguments. In C, specifying void inside the
parameter list explicitly denotes that the function takes zero
arguments. While int main() is widely used, in standards
prior to C23, empty parentheses signified an unspecified number of
parameters rather than none. In C23, int main() and
int main(void) are completely equivalent.
2. Command-Line Arguments
int main(int argc, char *argv[])or the functionally equivalent:
int main(int argc, char **argv)This signature allows the program to receive arguments passed from the command line or executing environment:
argc(Argument Count): A non-negative integer representing the number of arguments passed to the program, including the program invocation name itself.argv(Argument Vector): An array of pointers to null-terminated character sequences (strings).argv[0]represents the program name (or an empty string if not available),argv[1]throughargv[argc - 1]represent the individual command-line parameters, and the standard mandates thatargv[argc]must always be a null pointer.
While the parameter names argc and argv are
used by convention, any valid C identifier can be used (e.g.,
int main(int count, char *strings[])), provided the types
match.
Implementation-Defined Signatures
The C standard allows an implementation to support alternative,
implementation-defined forms of the main function, provided
the return type remains compatible with int.
A common third parameter supported on POSIX and Unix-like platforms provides access to environment variables:
int main(int argc, char *argv[], char *envp[])Here, envp is a null-terminated array of pointers to
environment variable strings. While valid on systems that explicitly
support it, this signature is not required by ISO C and reduces code
portability compared to the standard two-parameter format used alongside
the standard getenv() function.
Freestanding Environments
In freestanding environments—such as operating system kernels,
bootloaders, and embedded systems running without an operating
system—there is no requirement for the program entry point to be named
main or to conform to any specific signature. The startup
method, name, and parameter requirements in freestanding systems are
entirely determined by the target architecture and hardware
implementation.