In C++, the main() function is the most important part of a program and it must return an int. This return value is a program exit status code that is sent back to the operating system when the program terminates and this article is dedicated to the analysis of why this restriction is in place, what it means, and what is considered as best practices while illustrating the concept using sample codes.
Standard Compliance
A significant standard compliance for C++ includes the requirement for the return type of the main function to be int. This is stated explicitly in the C++ standard (ISO/IEC 14882), where it is defined as giving the function signature:
int main();
int main(int argc, char* argv[]);
Why is void not a main()?
A void return type does not ask for a return statement, so some programmers might wonder why we cannot use void main-but this is actually a non-compliant violation against C++ standards and defines the undefined behavior. While non-compliant compilation rules may not sometimes strictly prohibit this, non-standard codes indeed become less portable across platforms or compilers, creating troubles while transferring codes from one system to another.
- Exit Status Is Communicated via An Integer
The return value of the main function is used to tell whether the program underwent or not an error during abnormal termination. That information is of particular importance to the user, to the operating system, since it shows the operating system how the program should be handled after it terminates.
Exit Status Codes:
return 0;
→ Indicates successful execution.return 1;
(or any nonzero value) → Indicates an error or abnormal termination.
For example, in a Linux or UNIX environment, running a program from the terminal allows checking the exit status using $?
:
./myprogram
echo $?
If myprogram
executes successfully and returns 0
, the shell prints 0
. If it fails and returns 1
, the shell prints 1
, indicating an error.
Example:
#include <iostream>
int main() {
std::cout << "Program executed successfully." << std::endl;
return 0; // Signals successful execution
}
A bug can possibly lead to a different value being returned if we induce one intentionally:
#include <iostream>
int main() {
std::cerr << "An error occurred!" << std::endl;
return 1; // Indicates an error
Having exit codes is also very beneficial when trying to integrate software to other systems that are larger. Scripts and or automation components can also help in such cases as they require determining what happens next when the exit code is set.
Compatibility with exit(int)
The C++ provides the exit function that is specified within the library of . It allows safe completion of a program and sends an exit code back to the return function. The concept of the normal termination of a program was introduced in section 3.1.5 when main ends by return.
Example with exit()
:
#include <iostream>
#include <cstdlib>
int main() {
std::cout << "Program is running..." << std::endl;
exit(0); // Terminates the program with success status
}
When a program has to terminate from a nested function, the exit() function can be useful:
#include <iostream>
#include <cstdlib>
void terminateProgram() {
std::cerr << "Critical error! Terminating program." << std::endl;
exit(1);
}
int main() {
terminateProgram();
return 0; // This line will never execute
}
Portability and Best Practice
It should be noted that the standardization ensures portability between various compiler execution and different OS which is the exact objective here and int main() is a simple code construct that helps in compliance. Several circumstances demand the implementation of portable codes considering the number of systems that the software has to be executed without any adjustment to sources.
For example, the same program can be compiled in different languages (within the gcc environment (in a Unix system), and within the Clang (LLVM-based compiler) environment, and later in the environment of the Microsoft Visual Studio (MSVC)).
In some cases (most of the poorly-defined implementations of JavaScript) using void main() can even be made into a syntactically valid code and work with some, specific, build-portable optimizations. Of course, int main() can be used to fix all these glitches and make it run.
- Understanding argc and argv.
The main function can also accept the following optional arguments:
int main(int argc, char* argv[]);
These arguments enable the program to accept the command line inputs.
Breaking it down:
argc (argument count): This argument represents the number of command line arguments passed, including the program’s name.
argv (argument vector): It is the one-dimensional array of parameters that can be passed to the program as a sequence of C-strings.
Example
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "Number of arguments: " << argc << std::endl;
for (int i = 0; i < argc; ++i) {
std::cout << "Argument " << i << ": " << argv[i] << std::endl;
}
return 0;
}
Output when executed with
./program Hello World
output
Number of arguments: 3
Argument 0: ./program
Argument 1: Hello
Argument 2: World
Historical view
Developers of older C would sometimes use void main () in the days before ANSI C and did not have to strictly return a value. This kind of behavior in C insider compilers of the newer days does not exist. However, modern C++ has incorporation quality control incorporated with strict compliance.
Embedded systems or microcontrollers can still use void main () as expected. The condition, however, does not perpetuate as a good standard in programming model of C++.
Final Conclusion
The directive that states a certain return type for the main function in C++ is not without any meaningful reason, rather it performs vital functions:
Efficiency of Program Compilation: Guarantees that its compilation is in accordance with what C++ demands.
Working with Exit Codes: Implicates the need for programs to signal their exit in a controlled manner.
Incidence of exit(int): This makes ending execution of a program quite manageable.
Working with an Unknown Organization: Such a close language provides that source does it in identical manner as its prose rather than in the manner of the level Language A which is rather like programming languages B or C.
Support for Command-Line Parameters: This parameter specifies whether the command is executed or not. The parameters written in the curly braces {} in the definition are optional.
Some implementers/compilers particularly Microsoft Visual C++ first for 2005 deliberately by design, and close the implementation of C++ is void main() but it is not recommended while writing C++; void main can be jeopardous if you want your code protected, portable or reusable. Hence, observing the pester practice of always employing int main() results in stable and compatible code across all domains.