The return value of the main function are you paying attention? Maybe someone would say that there can be no return value, if you drill down into the program's CRT startup code, you'll find ....
1 __initenv = envp; 2 Mainret = Main (argc, argv, envp); 3 if (!managedapp) 4 exit (Mainret); 5 0 )6 cexit ();
According to the new C99 standard, even if the function itself does not have a return value defined, the compiler adds it to return to the firing program's running state. Many people even have some books on the market that use void main (), which is actually wrong. void Main () has never been defined in C + +. C + + 's father, Bjarne Stroustrup, explicitly wrote in the FAQ on his homepage that the definition void main () {/* ... */} is not and never have been C + +, nor Has it even been c. (void Main () is never present in C + + or C). The following is a separate definition of the main function in the C and C + + standards.
(1) In C language
In C89, main () is acceptable. The classic masterpiece of Brian W. Kernighan and Dennis M. Ritchie, the C programming Language 2e (second edition of the C programming language), is the main (). However, in the latest C99 standard, only the following two definitions are correct:
int main (void)
int main (int argc, char *argv[])
(reference: ISO/IEC 9899:1999 (E) programming languages-c 5.1.2.2.1 program startup)
Of course, we can make a small change. For example: Char *argv[] can be written as Char **argv;argv and ARGC can be changed to other variable names (such as Intval and Charval), but be sure to conform to the naming conventions of the variables. If you do not need to get arguments from the command line, use int main (void), or use int main (int argc, char *argv[]). The return value type of the main function must be int so that the return value can be passed to the program's activator (such as the operating system). If the return statement is not written at the end of the main function, C99 specifies that the compiler automatically adds return 0 to the generated target file (e.g. EXE file); , indicating that the program exited normally. However, I suggest you better add the return statement at the end of the main function, although this is not necessary, but it is a good habit. Note that VC6 does not include return 0 in the target file; , presumably because VC6 is a 98 product, so this feature is not supported. Now understand why it is advisable to add a return statement! However, GCC3.2 (C compiler under Linux) adds return 0 to the generated target file.
(2) in the C + + language
The following two types of main functions are defined in c++98:
int main ()
int main (int argc, char *argv[])
(reference: ISO/IEC 14882 (1998-9-01) programming languages-c++ 3.6 Start and termination)
int main () is equivalent to int main (void) in C99, and the use of int main (int argc, char *argv[]) is also defined in C99. Similarly, the return value type of the main function must also be int. If the return statement is not written at the end of the main function, c++98 specifies that the compiler automatically adds return 0 to the generated target file. Similarly, VC6 does not support this feature, but g++3.2 (c + + compiler under Linux) is supported.
(3) about void Main and int main
A lot of C programmers have been mistaken for the idea that such a function does not accept any parameters: int foo (); In fact, this function is considered to accept the unknown number of parameters (translation: can accept any number of parameters!) )。 The correct usage is to add the keyword void within the parentheses.
In C and C + +, function prototypes that do not receive any parameters and return no information are "void foo (void);". Probably because of this, many people mistakenly think that if you do not need the program return value, you can define the main function as void main (void). However, this is wrong! The return value of the main function should be defined as type int, as specified in the C and C + + standards. Although in some compilers, void main can be compiled (such as VC6), not all compilers support void Main, since void main is never defined in the standard. g++3.2 if the return value of the main function is not of type int, it will not compile at all. The GCC3.2 will issue a warning. So, if you want your program to have good portability, be sure to use int main. In summary: void main main function has no return value, and main defaults to int, which is int main (), which returns an integer. Note that the new standard does not allow the default return value, that is, int cannot be saved, and the corresponding main function no longer supports void return values, so in order for the program to be well-ported, it is highly recommended to use:
int main ()
{
return 0; /* Return value of the new standard main function This statement can be omitted */
}
The function of the return value: The return value of the main function is used to describe the program's exit status. If 0 is returned, the program exits normally, and the meaning of the other numbers is determined by the system. Typically, the return of a non-0 delegate program exits unexpectedly. Below we do a small experiment under the WinXP environment. First compile the following program:
int main (void)
{
return 0;
}
Then open the attachment "command Prompt" in the command line to run the just compiled executable file, and then enter "echo%errorlevel%", return, you can see the return value of the program is 0. Assuming that the file you just compiled is a.exe, if you enter "a && dir", the folders and files in the current directory are listed. However, if you change to "return-1", or another value other than 0, the Dir will not execute if you recompile and enter "a && dir". Because && means: If the previous program in && exits normally, it will continue to execute && the subsequent program, otherwise it will not execute. That is, by using the return value of the program, we can control the execution of the next program. This is the benefit of int main. If you are interested, you can also change the return value type of the main function to a non-int type (such as float), recompile and execute "a && dir", and see what happens, and think about why that happened. By the way, if you enter a | | Dir, then the dir is executed if a exits unexpectedly.
Finally, about why void main (void) is a wrong use, here is a more detailed English article:
void main (void)-The wrong Thing The newsgroup, comp.lang.c, is plagued by a almost continuous discussion of whether we can or cannot use void as A return type for main. The ANSI standard says "No", which should is an end of it. However, a number of beginners ' books on C has used void main (void) in all of the their examples, leading to a huge Number of people who don ' t know any better. When people ask what using a void is wrong (since it seems to work), the answer is usually one of the following:
- Because the says so.
(to which the answer was usually of the form "butit works for me!")
- Because the startup routines that call main could is assuming that the return value would be pushed onto the stack . If Main () does not does this, then this could leads to stack corruption in the program's exit sequence, and cause it to crash.
(to which the answer was usually of the form "butit works for me!")
- Because you is likely to return a random value to the invokation environment. This is bad, because if someone wants to check whether your program failed, or to call your program from a makefile, then They won ' t is able to guarantee, that a Non-zero return code implies failure.
(to which the answer was usually of the form "that' s their Problem").
This page demonstrates a system on which a void main (void) program would very likely cause problems in the third C Lass above. Calling the program from a script may cause the script to die, whether or not it return code is checked. Calling it from a makefile could cause make to complain. Calling it from the command line may cause a error to be reported. RISC OS is the native operating system of Acorn ' s range of ARM based computers. One of the facilities of this OS is a system variable, sys$rclimit. The value of this variable specifies the maximum value, a program could return to the OS without causing RISC OS itself To raise an error. The default value of this variable are set by the OS at 256. I ' m not too sure what's the intended function of this variable is, but it's exists, and that's that. Now, let's look at a example program using int main (void). int main (void) { return 42;} compiling it to ARM assembly language, using GCC (AS-aside:acorn ' s own C compiler reports a warning with void Main (void) and converts it to an integer function returning zero) gives the following:
|main|: mov IP, SP stmfd sp!, {RFP, FP, IP, LR, PC} sub FP, IP, #4 cmps SP,SL bllt |x$stack_overflow| BL |___main| mov r0, #42 ldmdb fp, {RFP, FP, SP, pc}^
The first six instructions is initialisation and stack checking. The final both return to the library startup code. So, the return value of the main is passed in R0. Note that the library startup code was expecting to call a function returning an integer, so would happily use the value RET urned in R0.What is happens with a void main function? Well, here's an example. #include <stdio.h>char buf[1024];void main (void) {(void) fgets (buf, 1024x768, stdin);} The program waits-a line of text from its standard input, nothing else. Again we compile it to assembler:
|. lc0|: DCD |__iob| |. lc1|: DCD |buf| | main|: mov IP, SP stmfd sp!, {RFP, FP, IP, LR, PC} sub FP, IP, #4 cmps sp,sl Bllt |x$stack_overflow| BL |___main| LDR R2, [pc, #|. lc0| - . -8] mov r1, #1024 ldr r0, [pc, #|. lc1| - . -8] bl |fgets| Ldmdb FP, {RFP, FP, SP, pc}^ area |buf|, DATA, COMMON, noinit % 1024
Again, the first six instructions in main set things up. The next three set up the "arguments for the" to fgets. Then we call fgets and return to the caller. stdio.h says that fgets returns a pointer to the buffer. So, in this instance, what we were returning to the library startup code was a pointer to BUF. Under RISC OS, all C programs is mapped into memory at 0x8000. So, we'll be returning a value to the OS which is > 32768 (hence, certainly > the default value of Sys$rclimit ). The OS then raises an error.Here's the result of compiling and running the program: Scsi:void% gcc void.c-o voiddrlink AOF Linker Version 0.28
And, in a script file: Scsi:void% cat Scriptvoidecho finishedscsi:void% run Scripti enter this Linereturn code too largescsi:void%
The error interrupts the script before the second command is run.Note that the example above is a little contrived in order to make the final function call return a pointer. A Better example where this could cause problems are one where the program uses printf to report a usage string > ch Aracters long prior to returning or, worse still, one where the program uses printf to output data depending on user input . Depending on the length of the user's input text, the program could or may not be cause an error which was solely due to the use of void as a return type for main. So, if you want your software to is portable, please make main return int. It does matter. |
about void Main and int main