c++ - main函数返回值 - return 0和return 1





What is the correct (most efficient) way to define the main() function in C and C++ — int main() or void main() — and why?

Those words "(most efficient)" don't change the question. Unless you're in a freestanding environment, there is one universally correct way to declare main() , and that's as returning int.

What should main() return in C and C++?

It's not what should main() return, it's what does main() return. main() is, of course, a function that someone else calls. You don't have any control over the code that calls main() . Therefore, you must declare main() with a type-correct signature to match its caller. You simply don't have any choice in the matter. You don't have to ask yourself what's more or less efficient, or what's better or worse style, or anything like that, because the answer is already perfectly well defined, for you, by the C and C+ standards. Just follow them.

If int main() then return 1 or return 0?

0 for success, nonzero for failure. Again, not something you need to (or get to) pick: it's defined by the interface you're supposed to be conforming to.


Omit return 0

When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main .

Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments: "I didn't know that." or "That's bad advice!" My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:

[...] 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; reaching the } that terminates the main function returns a value of 0.

For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:

If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird" . If, like me, you're curious about the rationale for the change to the C standard read this question . Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.


main() in C89 and K&R C unspecified return types default to 'int`.

return 1? return 0?
  1. If you do not write a return statement in int main() , the closing { will return 0 by default.

  2. return 0 or return 1 will be received by the parent process. In a shell it goes into a shell variable, and if you are running your program form a shell and not using that variable then you need not worry about the return value of main() .

See How can I get what my main function has returned? 。

$ ./a.out
$ echo $?

This way you can see that it is the variable $? which receives the least significant byte of the return value of main() .

In Unix and DOS scripting, return 0 on success and non-zero for error are usually returned. This is the standard used by Unix and DOS scripting to find out what happened with your program and controlling the whole flow.


main的返回值应指示程序如何退出。 正常退出通常由来自main返回值0表示。 异常终止通常以非零返回来表示,但对于如何解释非零代码没有标准。 同样如其他人所指出的, void main()被C ++标准明确禁止,不应该被使用。 有效的C ++ main签名是:

int main()

int main(int argc, char* argv[])

相当于

int main(int argc, char** argv)

值得注意的是,在C ++中, int main()可以不带返回值,此时它默认返回0.这对于C99程序也是如此。 是否应该省略返回0是否可以辩论。 有效的C程序主签名的范围要大得多。

而且, main功能的效率不是问题。 它只能根据C ++标准进入并留下一次(标记程序开始和终止)。 对于C来说,情况是不同的,允许重新输入main() ,但应该可以避免。


I was under the impression that standard specifies that main doesn't need a return value as a successful return was OS based (zero in one could be either a success or a failure in another), therefore the absence of return was a cue for the compiler to insert the successful return itself.

However I usually return 0.


If you really have issues related to efficiency of returning an integer from a process, you should probably avoid to call that process so many times that this return value becomes an issue.

If you are doing this (call a process so many times), you should find a way to put your logic directly inside the caller, or in a DLL file, without allocate a specific process for each call; the multiple process allocations bring you the relevant efficiency problem in this case.

In detail, if you only want to know if returning 0 is more or less efficient than returning 1, it could depend from the compiler in some cases, but generically, assuming they are read from the same source (local, field, constant, embedded in the code, function result, etc.) it requires exactly the same number of clock cycles.


Keep in mind that,even though you're returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255).


Returning 0 should tell the programmer that the program has successfully finished the job.


The return value of main() shows how the program exited. If the return value is zero it means that the execution was successful while any non-zero value will represent that something went bad in the execution.


This basically depends on your execution environment (the OS). C implies that it will be run by a UNIX like OS which expects the program to return a (small? 1 Byte? can't remember) integer to indicate success / failure.

You should probably just use int main(int argc, char** argv) .


成功返回0,错误返回非零。 这是UNIX和DOS脚本使用的标准来查明你的程序发生了什么。


我相信main()应该返回EXIT_SUCCESSEXIT_FAILURE 。 它们在stdlib.h中定义


请注意,C和C ++标准定义了两种实现方式:独立式和托管式。

  • C90托管环境

    允许的形式1

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    注释:

    前两者明确表示为允许的形式,其他则隐式允许,因为C90允许“隐式int”用于返回类型和函数参数。 没有其他形式是允许的。

  • C90独立式环境

    任何形式或名称的主要被允许2

  • C99托管环境

    允许的形式3

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    注释:

    C99删除了“隐式int”,所以main()不再有效。

    引入了一个奇怪的,含糊不清的句子或“某种其他实现定义的方式”。 这可以解释为“ int main()的参数可能会有所不同”或者“main可以有任何实现定义的形式”。

    一些编译器选择以后一种方式解释标准。 可以说,人们不能轻易表明,他们并不严格遵守标准本身,因为它是模棱两可的。

    但是,为了允许完全疯狂的main()形式可能(?)不是这个新句子的意图。 C99的基本原理(不是规范的)意味着该句子引用了int main 4的其他参数。

    然而,托管环境项目终止部分继续争论主要不返回整数5的情况 。 虽然该部分对于主要应该如何声明并不规范,但它肯定意味着即使在托管系统上主要可以以完全实现定义的方式来声明。

  • C99独立式环境

    任何形式或名称的主要是允许的6

  • C11托管环境

    允许的形式7

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11独立式环境

    任何形式或名称的主要被允许8

请注意,在任何上述版本中, int main()从未被列为C的任何托管实现的有效表单。 在C中,与C ++不同, ()(void)具有不同的含义。 前者是可以从语言中删除的过时特征。 请参阅C11未来的语言指导:

6.11.6函数声明符

具有空括号的函数声明符(不是原型格式参数类型声明符)的使用是过时的功能。

  • C ++ 03托管环境

    允许的形式9

    int main ()
    int main (int argc, char *argv[])
    

    注释:

    请注意第一种形式的空括号。 C ++和C在这种情况下是不同的,因为在C ++中这意味着该函数不带参数。 但在C中,这意味着它可能需要任何参数。

  • C ++ 03独立环境

    在启动时调用的函数的名称是实现定义的。 如果它被命名为main()它必须遵循规定的形式10

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • C ++ 11托管环境

    允许的形式11

    int main ()
    int main (int argc, char *argv[])
    

    注释:

    该标准的文字已被更改,但含义相同。

  • C ++ 11独立环境

    在启动时调用的函数的名称是实现定义的。 如果它被命名为main()它必须遵循规定的形式12

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

参考

  1. ANSI X3.159-1989 2.1.2.2托管环境。 “程序启动”

    程序启动时调用的函数名为main。 该实现没有声明这个函数的原型。 它应该用int的返回类型定义,并且不带参数:

    int main(void) { /* ... */ } 
    

    或者带有两个参数(这里称为argc和argv,尽管可以使用任何名称,因为它们是声明它们的函数的本地):

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3.159-1989 2.1.2.1独立环境:

    在一个独立的环境中(C程序的执行可能没有任何操作系统的好处),程序启动时调用的函数的名称和类型是实现定义的。

  3. ISO 9899:1999 5.1.2.2托管环境 - > 5.1.2.2.1程序启动

    程序启动时调用的函数名为main。 该实现没有声明这个函数的原型。 它应该用int的返回类型定义,并且不带参数:

    int main(void) { /* ... */ } 
    

    或者带有两个参数(这里称为argc和argv,尽管可以使用任何名称,因为它们是声明它们的函数的本地):

    int main(int argc, char *argv[]) { /* ... */ }
    

    或等同物; 9)或以某种其他实施方式定义的方式。

  4. 国际标准的基本原理 - 编程语言 - C,修订5.10。 5.1.2.2托管环境 - > 5.1.2.2.1程序启动

    主要参数以及exit,main和atexit(参见§7.20.4.2)的相互作用的行为已被编纂为抑制argv字符串表示形式中某些不需要的变体,以及由main返回的值的含义。

    argc和argv作为主要参数的规范认可了大量先前的实践。 argv [argc]必须是一个空指针,以便根据惯例为列表的末尾提供冗余检查。

    main是唯一可以用0或2个参数声明的函数。 (其他函数参数的数量必须与调用和定义完全匹配)。这种特殊情况简单地认识到当程序不访问程序参数字符串时,将参数从主参数中删除的普遍做法。 虽然许多实现支持两个以上的主要参数,但这样的实践既不被标准祝福也不被禁止; 一个用三个参数定义主体的程序并不严格符合(见§5.5.1)。

  5. ISO 9899:1999 5.1.2.2 Hosted environment --> 5.1.2.2.3 Program termination

    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.

  6. ISO 9899:1999 5.1.2.1 Freestanding environment

    In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined.

  7. ISO 9899:2011 5.1.2.2 Hosted environment -> 5.1.2.2.1 Program startup

    This section is identical to the C99 one cited above.

  8. ISO 9899:1999 5.1.2.1 Freestanding environment

    This section is identical to the C99 one cited above.

  9. ISO 14882:2003 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. 它应该有一个类型为int的返回类型,否则它的类型是实现定义的。 All implementations shall allow both of the following definitions of main:

    int main() { /* ... */ }
    

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882:2003 3.6.1 Main function

    It is implementation-defined whether a program in a freestanding environment is required to define a main function.

  11. ISO 14882:2011 3.6.1 Main function

    An implementation shall not predefine the main function. This function shall not be overloaded. 它应该有一个类型为int的返回类型,否则它的类型是实现定义的。 All implementations shall allow both

    — a function of () returning int and

    — a function of (int, pointer to pointer to char) returning int

    as the type of main (8.3.5).

  12. ISO 14882:2011 3.6.1 Main function

    This section is identical to the C++03 one cited above.





return-type