main() 在 C 和 C++ 中应该返回什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/204476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:42:02  来源:igfitidea点击:

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

c++creturn-valuemainreturn-type

提问by Joel

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

main()在 C 和 C++ 中定义函数的正确(最有效)方法是什么——int main()或者void main()——为什么?如果int main()然后return 1return 0



There are numerous duplicates of this question, including:

这个问题有很多重复,包括:

Related:

有关的:

采纳答案by workmad3

The return value for mainindicates how the program exited. Normal exit is represented by a 0 return value from main. Abnormal exit is signaled by a non-zero return, but there is no standard for how non-zero codes are interpreted. As noted by others, void main()is prohibited by the C++ standard and should not be used. The valid C++ mainsignatures are:

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

int main()

and

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

which is equivalent to

这相当于

int main(int argc, char** argv)

It is also worth noting that in C++, int main()can be left without a return-statement, at which point it defaults to returning 0. This is also true with a C99 program. Whether return 0;should be omitted or not is open to debate. The range of valid C program main signatures is much greater.

还值得注意的是,在 C++ 中,int main()可以不使用 return 语句,此时它默认返回 0。这对于 C99 程序也是如此。是否return 0;应该省略还有待商榷。有效的 C 程序主签名的范围要大得多。

Efficiency is not an issue with the mainfunction. It can only be entered and left once (marking the program's start and termination) according to the C++ standard. For C, re-entering main()is allowed, but should be avoided.

效率不是main函数的问题。根据C++标准,它只能进入和离开一次(标记程序的开始和终止)。对于 C,main()允许重新输入,但应避免。

回答by Chris Young

The accepted answer appears to be targetted for C++, so I thought I'd add an answer that pertains to C, and this differs in a few ways.

接受的答案似乎是针对 C++ 的,所以我想我会添加一个与 C 相关的答案,这在几个方面有所不同。

ISO/IEC 9899:1989 (C90):

ISO/IEC 9899:1989 (C90):

main()should be declared as either:

main()应声明为:

int main(void)
int main(int argc, char **argv)

Or equivalent. For example, int main(int argc, char *argv[])is equivalent to the second one. Further, the intreturn type can be omitted as it is a default.

或同等学历。例如,int main(int argc, char *argv[])相当于第二个。此外,int返回类型可以省略,因为它是默认值。

If an implementation permits it, main()can be declared in other ways, but this makes the program implementation defined, and no longer strictly conforming.

如果实现允许,main()可以用其他方式声明,但这会使程序实现被定义,不再严格遵守。

The standard defines 3 values for returning that are strictly conforming (that is, does not rely on implementation defined behaviour): 0and EXIT_SUCCESSfor a successful termination, and EXIT_FAILUREfor an unsuccessful termination. Any other values are non-standard and implementation defined. main()must have an explicit returnstatement at the end to avoid undefined behaviour.

该标准定义了用于返回严格遵循(即不依赖于实现定义的行为)3个值:0EXIT_SUCCESS一个成功的终止,以及EXIT_FAILURE对不成功的终止。任何其他值都是非标准和实现定义的。main()最后必须有一个明确的return声明,以避免未定义的行为。

Finally, there is nothing wrong from a standards point of view with calling main()from a program.

最后,从标准的角度来看,main()从程序中调用没有任何问题。

ISO/IEC 9899:1999 (C99):

ISO/IEC 9899:1999 (C99):

For C99, everything is the same as above except:

对于 C99,除了:

  • The intreturn type may not be omitted.
  • You may omit the return statement from main(). If you do, and main()finished, there is an implicit return 0.
  • int返回类型不能省略。
  • 您可以从 中省略 return 语句main()。如果你这样做了,并main()完成了,有一个隐含的return 0.

回答by Jonathan Leffler

Standard C — Hosted Environment

标准 C — 托管环境

For a hosted environment (that's the normal one), the C11 standard (ISO/IEC 9899:2011) says:

对于托管环境(这是正常环境),C11 标准 (ISO/IEC 9899:2011) 说:

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 intand with no parameters:

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

or with two parameters (referred to here as argcand 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.

If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argcshall be nonnegative.
  • argv[argc]shall be a null pointer.
  • If the value of argcis greater than zero, the array members argv[0]through argv[argc-1]inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
  • If the value of argcis greater than zero, the string pointed to by argv[0]represents the program name; argv[0][0]shall be the null character if the program name is not available from the host environment. If the value of argcis greater than one, the strings pointed to by argv[1]through argv[argc-1]represent the program parameters.
  • The parameters argcand argvand the strings pointed to by the argvarray shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

10)Thus, intcan be replaced by a typedef name defined as int, or the type of argvcan be written as char **argv, and so on.

5.1.2.2.1 程序启动

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

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

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

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

或同等学历; 10)或以其他一些实现定义的方式。

如果声明了它们,则主函数的参数应遵守以下约束:

  • 的值argc应为非负。
  • argv[argc]应为空指针。
  • 如果 的值argc大于零,则argv[0]通过 argv[argc-1]inclusive的数组成员应包含指向字符串的指针,这些字符串在程序启动之前由主机环境赋予实现定义的值。目的是从托管环境中的其他地方向程序启动之前确定的程序提供信息。如果宿主环境无法提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串。
  • 如果 的值argc大于零,则指向的字符串argv[0]表示程序名称;argv[0][0]如果程序名在宿主环境中不可用,则应为空字符。如果 的值argc大于 1,则argv[1]通过指向的字符串argv[argc-1]表示程序参数。
  • 数组指向的参数argcargv字符串argv应可由程序修改,并在程序启动和程序终止之间保留其最后存储的值。

10)因此,int可以替换为定义为 的 typedef 名称int,或者argv可以将的类型写为 char **argv,依此类推。

Program termination in C99 or C11

C99 或 C11 中的程序终止

The value returned from main()is transmitted to the 'environment' in an implementation-defined way.

返回的值main()以实现定义的方式传输到“环境”。

5.1.2.2.3 Program termination

1 If the return type of the mainfunction is a type compatible with int, a return from the initial call to the mainfunction is equivalent to calling the exitfunction with the value returned by the mainfunction as its argument;11)reaching the }that terminates the mainfunction 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 mainwill have ended in the former case, even where they would not have in the latter.

5.1.2.2.3 程序终止

1 如果main函数的返回类型是与兼容的类型int,则从最初调用该main函数的返回相当于以该exit函数返回的值main作为参数调用该函数;11)到达}终止 main函数的 返回值 0。如果返回类型与 不兼容int,则返回给宿主环境的终止状态是未指定的。

11)根据 6.2.4,在 中声明的具有自动存储持续时间的对象的生命周期main将在前一种情况下结束,即使它们在后一种情况下不会结束。

Note that 0is mandated as 'success'. You can use EXIT_FAILUREand EXIT_SUCCESSfrom <stdlib.h>if you prefer, but 0 is well established, and so is 1. See also Exit codes greater than 255 — possible?.

请注意,这0被要求为“成功”。如果您愿意,您可以使用EXIT_FAILUREand EXIT_SUCCESSfrom <stdlib.h>,但 0 已确定,1 也是如此。另请参阅退出代码大于 255 — 可能吗?.

In C89 (and hence in Microsoft C), there is no statement about what happens if the main()function returns but does not specify a return value; it therefore leads to undefined behaviour.

在 C89 中(因此在 Microsoft C 中),没有关于如果main()函数返回但未指定返回值会发生什么的声明;因此,它会导致未定义的行为。

7.22.4.4 The exitfunction

?5 Finally, control is returned to the host environment. If the value of statusis zero or EXIT_SUCCESS, an implementation-defined form of the status successful terminationis returned. If the value of statusis EXIT_FAILURE, an implementation-defined form of the status unsuccessful terminationis returned. Otherwise the status returned is implementation-defined.

7.22.4.4exit功能

?5 最后,控制权返回到宿主环境。如果 的值status为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果值statusEXIT_FAILURE,地位的实现定义的形式成功终止返回。否则返回的状态是实现定义的。

Standard C++ — Hosted Environment

标准 C++ — 托管环境

The C++11 standard (ISO/IEC 14882:2011) says:

C++11 标准 (ISO/IEC 14882:2011) 说:

3.6.1 Main function [basic.start.main]

?1 A program shall contain a global function called main, which is the designated start of the program. [...]

?2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation defined. All implementations shall allow both of the following definitions of main:

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

and

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

In the latter form argcshall be the number of arguments passed to the program from the environment in which the program is run. If argcis nonzero these arguments shall be supplied in argv[0]through argv[argc-1]as pointers to the initial characters of null-terminated multibyte strings (NTMBSs) (17.5.2.1.4.2) and argv[0]shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "". The value of argcshall be non-negative. The value of argv[argc]shall be 0. [ Note: It is recommended that any further (optional) parameters be added after argv. —end note ]

?3 The function mainshall not be used within a program. The linkage (3.5) of mainis implementation-defined. [...]

?5 A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exitwith the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing

return 0;

3.6.1 主函数【basic.start.main】

?1 程序应包含一个名为 main 的全局函数,它是程序的指定开始。[...]

?2 实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许以下两个 main 定义:

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

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

后一种形式argc应为从程序运行的环境传递给程序的参数数量。如果argc是非零这些参数应在提供argv[0]通过argv[argc-1]作为指针指向空终止多字节串的初始字符(NTMBSs)(17.5.2.1.4.2)和argv[0]应为指针NTMBS的初始字符,表示用来名称调用程序或"". 的值argc应为非负数。的值argv[argc]应为 0。 [注意:建议在 之后添加任何其他(可选)参数argv。——尾注]

?3 该功能main不得在程序中使用。的链接 (3.5)main是实现定义的。[...]

?5 main 中的 return 语句具有离开 main 函数(销毁任何具有自动存储期的对象)并std::exit以返回值作为参数调用的效果。如果控制到达 main 的末尾,没有遇到 return 语句,效果就是执行

return 0;

The C++ standard explicitly says "It [the main function] shall have a return type of type int, but otherwise its type is implementation defined", and requires the same two signatures as the C standard to be supported as options. So a 'void main()' is directly not allowed by the C++ standard, though there's nothing it can do to stop a non-standard implementation allowing alternatives. Note that C++ forbids the user from calling main(but the C standard does not).

C++ 标准明确规定“它 [主函数] 应具有 type 的返回类型int,否则其类型是实现定义的”,并且需要与 C 标准相同的两个签名作为选项支持。因此,C++ 标准直接不允许“void main()”,尽管它无法阻止允许替代方案的非标准实现。请注意,C++ 禁止用户调用main(但 C 标准没有)。

There's a paragraph of §18.5 Start and terminationin the C++11 standard that is identical to the paragraph from §7.22.4.4 The exitfunctionin the C11 standard (quoted above), apart from a footnote (which simply documents that EXIT_SUCCESSand EXIT_FAILUREare defined in <cstdlib>).

C++11 标准中有一段 §18.5开始和终止与 §7.22.4.4 C11 标准中exit函数(上面引用的)相同,除了脚注(它只是记录EXIT_SUCCESSEXIT_FAILURE定义在<cstdlib>)。

Standard C — Common Extension

标准 C — 通用扩展

Classically, Unix systems support a third variant:

传统上,Unix 系统支持第三种变体:

int main(int argc, char **argv, char **envp) { ... }

The third argument is a null-terminated list of pointers to strings, each of which is an environment variable which has a name, an equals sign, and a value (possibly empty). If you do not use this, you can still get at the environment via 'extern char **environ;'. This global variable is unique among those in POSIX in that it does not have a header that declares it.

第三个参数是一个以空字符结尾的字符串指针列表,每个字符串都是一个环境变量,它有一个名称、一个等号和一个值(可能为空)。如果您不使用它,您仍然可以通过“ extern char **environ;”获取环境。这个全局变量在 POSIX 中是独一无二的,因为它没有声明它的头。

This is recognized by the C standard as a common extension, documented in Annex J:

这被 C 标准认可为通用扩展,记录在附件 J 中:

J.5.1 Environment arguments

?1 In a hosted environment, the main function receives a third argument, char *envp[], that points to a null-terminated array of pointers to char, each of which points to a string that provides information about the environment for this execution of the program (5.1.2.2.1).

J.5.1 环境参数

?1 在托管环境中,主函数接收第三个参数 ,char *envp[]该参数指向指向 的以空字符结尾的指针数组char,每个指针指向一个字符串,该字符串提供有关此程序执行的环境信息(5.1. 2.2.1)。

Microsoft C

微软C

The Microsoft VS 2010compiler is interesting. The web site says:

微软VS 2010的编译器是有趣的。该网站说:

The declaration syntax for main is

 int main();

or, optionally,

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

Alternatively, the mainand wmainfunctions can be declared as returning void(no return value). If you declare mainor wmainas returning void, you cannot return an exit code to the parent process or operating system by using a return statement. To return an exit code when mainor wmainis declared as void, you must use the exitfunction.

main 的声明语法是

 int main();

或者,可选地,

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

或者,mainwmain函数可以声明为返回void(无返回值)。如果声明mainwmain返回 void,则不能使用 return 语句将退出代码返回给父进程或操作系统。要在mainwmain声明为时返回退出代码void,您必须使用该exit函数。

It is not clear to me what happens (what exit code is returned to the parent or OS) when a program with void main()does exit — and the MS web site is silent too.

我不清楚当程序void main()退出时会发生什么(返回给父级或操作系统的退出代码是什么)——而且 MS 网站也处于沉默状态。

Interestingly, MS does not prescribe the two-argument version of main()that the C and C++ standards require. It only prescribes a three argument form where the third argument is char **envp, a pointer to a list of environment variables.

有趣的是,MS 没有规定main()C 和 C++ 标准要求的双参数版本。它只规定了一个三参数形式,其中第三个参数是char **envp,一个指向环境变量列表的指针。

The Microsoft page also lists some other alternatives — wmain()which takes wide character strings, and some more.

Microsoft 页面还列出了一些其他替代方案——wmain()它们采用宽字符串,等等。

The Microsoft Visual Studio 2005version of this pagedoes not list void main()as an alternative. The versionsfrom Microsoft Visual Studio 2008onwards do.

此页面的 Microsoft Visual Studio 2005版本未作为替代列出。Microsoft Visual Studio 2008以后的版本可以。void main()

Standard C — Freestanding Environment

标准 C — 独立环境

As noted early on, the requirements above apply to hosted environments. If you are working with a freestanding environment (which is the alternative to a hosted environment), then the standard has much less to say. For a freestanding environment, the function called at program startup need not be called mainand there are no constraints on its return type. The standard says:

如前所述,上述要求适用于托管环境。如果您正在使用独立环境(这是托管环境的替代方案),那么标准就没有什么可说的了。对于独立环境,不需要调用程序启动时调用的函数,main并且对其返回类型没有限制。标准说:

5.1.2 Execution environments

Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.

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. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.

The effect of program termination in a freestanding environment is implementation-defined.

5.1.2 执行环境

定义了两种执行环境:独立式和托管式。在这两种情况下,程序启动都是在执行环境调用指定的 C 函数时发生的。所有具有静态存储持续时间的对象都应在程序启动前进行初始化(设置为其初始值)。否则未指定此类初始化的方式和时间。程序终止将控制权返回给执行环境。

5.1.2.1 独立环境

在独立环境中(在这种环境中,C 程序可以在没有任何操作系统优势的情况下执行),程序启动时调用的函数的名称和类型是实现定义的。除了第 4 条要求的最小集合之外,任何独立程序可用的库设施都是实现定义的。

独立环境中程序终止的影响是实现定义的。

The cross-reference to clause 4 Conformance refers to this:

对第 4 条一致性的交叉引用是指:

?5 A strictly conforming programshall use only those features of the language and library specified in this International Standard.3)It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.

?6 The two forms of conforming implementation are hostedand freestanding. A conforming hosted implementationshall accept any strictly conforming program. A conforming freestanding implementationshall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.4)

?7 A conforming programis one that is acceptable to a conforming implementation.5)

3)A strictly conforming program can use conditional features (see 6.10.8.3) provided the use is guarded by an appropriate conditional inclusion preprocessing directive using the related macro. For example:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4)This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.

5)Strictly conforming programs are intended to be maximally portable among conforming implementations. Conforming programs may depend upon non-portable features of a conforming implementation.

?5严格遵守的程序应仅使用本国际标准中规定的语言和库的那些特性。3)它不应产生依赖于任何未指定、未定义或实现定义的行为的输出,并且不应超过任何最小实现限制。

?6 两种形式的一致性实现是托管独立的。一个符合托管实施应当接受任何严格符合程序。甲符合独立执行应接受任何严格符合程序,其中使用的库条款(第7节)中指定的功能被限制在标准报头的内容<float.h><iso646.h><limits.h><stdalign.h><stdarg.h><stdbool.h><stddef.h><stdint.h>,和 <stdnoreturn.h>。符合要求的实现可以有扩展(包括附加的库函数),只要它们不改变任何严格符合程序的行为。4)

?7一致程序是一致实现可接受的程序5)

3)严格遵守的程序可以使用条件特性(见 6.10.8.3),前提是该使用由使用相关宏的适当条件包含预处理指令保护。例如:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4)这意味着,除了在本国际标准中明确保留的标识符外,符合标准的实现不保留任何标识符。

5)严格一致的程序旨在在一致的实现之间最大限度地可移植。一致性程序可能依赖于一致性实现的不可移植特性。

It is noticeable that the only header required of a freestanding environment that actually defines any functions is <stdarg.h>(and even those may be — and often are — just macros).

值得注意的是,实际定义任何函数的独立环境所需的唯一标头是<stdarg.h>(甚至那些可能——而且通常是——只是宏)。

Standard C++ — Freestanding Environment

标准 C++ — 独立环境

Just as the C standard recognizes both hosted and freestanding environment, so too does the C++ standard. (Quotes from ISO/IEC 14882:2011.)

正如 C 标准识别托管环境和独立环境一样,C++ 标准也是如此。(引自 ISO/IEC 14882:2011。)

1.4 Implementation compliance [intro.compliance]

?7 Two kinds of implementations are defined: a hosted implementationand a freestanding implementation. For a hosted implementation, this International Standard defines the set of available libraries. A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries (17.6.1.3).

?8 A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.

?9 Each implementation shall include documentation that identifies all conditionally-supported constructs that it does not support and defines all locale-specific characteristics.3

3)This documentation also defines implementation-defined behavior; see 1.9.

17.6.1.3 Freestanding implementations [compliance]

Two kinds of implementations are defined: hosted and freestanding (1.4). For a hosted implementation, this International Standard describes the set of available headers.

A freestanding implementation has an implementation-defined set of headers. This set shall include at least the headers shown in Table 16.

The supplied version of the header <cstdlib>shall declare at least the functions abort, atexit, at_quick_exit, exit, and quick_exit(18.5). The other headers listed in this table shall meet the same requirements as for a hosted implementation.

Table 16 — C++ headers for freestanding implementations

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

1.4 实施合规性 [intro.compliance]

?7 定义了两种实现:托管实现独立实现。对于托管实现,此国际标准定义了可用库集。独立实现是一种可以在没有操作系统优势的情况下执行的实现,并且具有一组实现定义的库,其中包括某些语言支持库 (17.6.1.3)。

?8 一个符合要求的实现可以有扩展(包括附加的库函数),只要它们不改变任何格式良好的程序的行为。需要实现来诊断使用这种根据本国际标准格式错误的扩展的程序。但是,这样做之后,他们就可以编译和执行此类程序。

?9 每个实现都应包括文档,用于标识所有它不支持的有条件支持的构造,并定义所有特定于语言环境的特征。3

3)本文档还定义了实现定义的行为;见 1.9。

17.6.1.3 独立实施[合规性]

定义了两种实现:托管和独立 (1.4)。对于托管实现,此国际标准描述了可用标头集。

独立的实现有一组实现定义的头文件。该集合应至少包括表 16 中所示的标题。

报头的提供的版本<cstdlib>应宣布至少功能abortatexitat_quick_exitexit,和quick_exit(18.5)。此表中列出的其他标头应满足与托管实现相同的要求。

表 16 — 独立实现的 C++ 头文件

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

What about using int main()in C?

int main()在 C 中使用怎么样?

The standard §5.1.2.2.1 of the C11 standard shows the preferred notation —?int main(void)— but there are also two examples in the standard which show int main(): §6.5.3.4 ?8and §6.7.6.3 ?20. Now, it is important to note that examples are not 'normative'; they are only illustrative. If there are bugs in the examples, they do not directly affect the main text of the standard. That said, they are strongly indicative of expected behaviour, so if the standard includes int main()in an example, it suggests that int main()is not forbidden, even if it is not the preferred notation.

C11 标准的标准 §5.1.2.2.1 显示了首选符号 -? int main(void)— 但标准中也有两个例子显示int main()§6.5.3.4 ?8§6.7.6.3 ?20。现在,重要的是要注意示例不是“规范的”;它们只是说明性的。如果示例中有错误,它们不会直接影响标准的正文。也就是说,它们强烈地表明了预期的行为,所以如果标准包含int main()在一个例子中,它表明这int main()不是被禁止的,即使它不是首选符号。

6.5.3.4 The sizeofand _Alignofoperators

?8 EXAMPLE 3 In this example, the size of a variable length array is computed and returned from a function:

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}

6.5.3.4sizeof_Alignof运算符

?8 示例 3 在此示例中,计算变长数组的大小并从函数返回:

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}

回答by dmityugov

I believe that main()should return either EXIT_SUCCESSor EXIT_FAILURE. They are defined in stdlib.h

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

回答by Lundin

Note that the C and C++ standards define two kinds of implementations: freestanding and hosted.

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

  • C90 hosted environment

    Allowed forms 1:

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

    Comments:

    The former two are explicitly stated as the allowed forms, the others are implicitly allowed because C90 allowed "implicit int" for return type and function parameters. No other form is allowed.

  • C90 freestanding environment

    Any form or name of main is allowed 2.

  • C99 hosted environment

    Allowed forms 3:

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

    Comments:

    C99 removed "implicit int" so main()is no longer valid.

    A strange, ambiguous sentence "or in some other implementation-defined manner" has been introduced. This can either be interpreted as "the parameters to int main()may vary" or as "main can have any implementation-defined form".

    Some compilers have chosen to interpret the standard in the latter way. Arguably, one cannot easily state that they are not strictly conforming by citing the standard in itself, since it is is ambiguous.

    However, to allow completely wild forms of main()was probably(?) not the intention of this new sentence. The C99 rationale (not normative) implies that the sentence refers to additional parameters to int main4.

    Yet the section for hosted environment program termination then goes on arguing about the case where main does not return int 5. Although that section is not normative for how main should be declared, it definitely implies that main might be declared in a completely implementation-defined way even on hosted systems.

  • C99 freestanding environment

    Any form or name of main is allowed 6.

  • C11 hosted environment

    Allowed forms 7:

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

    Any form or name of main is allowed 8.

  • 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 独立环境

    允许使用任何形式或名称的 main 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 main4 的附加参数。

    然而,托管环境程序终止部分继续争论 main 不返回 int 5 的情况。尽管该部分不是关于如何声明 main 的规范,但它肯定意味着即使在托管系统上也可以以完全实现定义的方式声明 main。

  • C99 独立环境

    任何形式或名称的 main 都是允许的6

  • C11 托管环境

    允许的表格7

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

    允许任何形式或名称的 main 8



Note that int main()was never listed as a valid form for any hosted implementation of C in any of the above versions. In C, unlike C++, ()and (void)have different meanings. The former is an obsolescent feature which may be removed from the language. See C11 future language directions:

请注意,int main()对于上述任何版本中的任何托管 C 实现,从未将其列为有效形式。在C中,不同于C++,()并且(void)有不同的含义。前者是一个过时的特性,可以从语言中删除。参见 C11 未来语言方向:

6.11.6 Function declarators

The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

6.11.6 函数声明符

使用带空括号的函数声明符(不是原型格式参数类型声明符)是一个过时的特性。



  • C++03 hosted environment

    Allowed forms 9:

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

    Comments:

    Note the empty parenthesis in the first form. C++ and C are different in this case, because in C++ this means that the function takes no parameters. But in C it means that it may take any parameter.

  • C++03 freestanding environment

    The name of the function called at startup is implementation-defined. If it is named main()it must follow the stated forms 10:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • C++11 hosted environment

    Allowed forms 11:

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

    Comments:

    The text of the standard has been changed but it has the same meaning.

  • C++11 freestanding environment

    The name of the function called at startup is implementation-defined. If it is named main()it must follow the stated forms 12:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • 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[])
    


References

参考

  1. ANSI X3.159-1989 2.1.2.2 Hosted environment. "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[]) { /* ... */ }
    
  2. ANSI X3.159-1989 2.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.

  3. ISO 9899:1999 5.1.2.2 Hosted environment -> 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.

  4. Rationale for International Standard — Programming Languages — C, Revision 5.10. 5.1.2.2 Hosted environment --> 5.1.2.2.1 Program startup

    The behavior of the arguments to main, and of the interaction of exit, main and atexit (see §7.20.4.2) has been codified to curb some unwanted variety in the representation of argv strings, and in the meaning of values returned by main.

    The specification of argc and argv as arguments to main recognizes extensive prior practice. argv[argc] is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.

    main is the only function that may portably be declared either with zero or two arguments. (The number of other functions' arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main when the program does not access the program argument strings. While many implementations support more than two arguments to main, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.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. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:

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

    and

    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. It shall have a return type of type int, but otherwise its type is implementation-defined. 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.

  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 程序启动

    main 的参数的行为,以及 exit、main 和 atexit 的交互行为(参见第 7.20.4.2 节)已被编纂,以抑制 argv 字符串表示中的一些不需要的变化,以及 main 返回值的含义。

    argc 和 argv 作为主要参数的规范认可了广泛的先前实践。argv[argc] 需要为空指针,以提供对列表末尾的冗余检查,也是基于惯例。

    main 是唯一可以使用零个或两个参数可移植地声明的函数。(其他函数的参数数量必须在调用和定义之间完全匹配。)这种特殊情况只是认识到当程序不访问程序参数字符串时将参数留给 main 的普遍做法。虽然许多实现支持两个以上的 main 参数,但标准既不祝福也不禁止这种做法;用三个参数定义 main 的程序并不严格遵守(参见 §J.5.1.)。

  5. ISO 9899:1999 5.1.2.2 托管环境 --> 5.1.2.2.3 程序终止

    如果 main 函数的返回类型是与 int 兼容的类型,则从初始调用 main 函数的返回相当于以 main 函数返回的值作为参数调用 exit 函数;11) 到达}终止main 函数返回值 0。如果返回类型与 int 不兼容,则返回给宿主环境的终止状态是未指定的。

  6. ISO 9899:1999 5.1.2.1 独立环境

    在独立环境中(在这种环境中,C 程序可以在没有任何操作系统优势的情况下执行),程序启动时调用的函数的名称和类型是实现定义的。

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

    本节与上面引用的 C99 相同。

  8. ISO 9899:1999 5.1.2.1 独立环境

    本节与上面引用的 C99 相同。

  9. ISO 14882:2003 3.6.1 主要功能

    实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许以下两个 main 定义:

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

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882:2003 3.6.1 主要功能

    独立环境中的程序是否需要定义主函数是实现定义的。

  11. ISO 14882:2011 3.6.1 主要功能

    实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许

    — 一个 () 返回 int 和的函数

    — 返回 int 的 (int, 指向指向 char 的指针的指针) 的函数

    作为主要的类型(8.3.5)。

  12. ISO 14882:2011 3.6.1 主要功能

    本节与上面引用的 C++03 相同。

回答by Lou Franco

Return 0 on success and non-zero for error. This is the standard used by UNIX and DOS scripting to find out what happened with your program.

成功时返回 0,错误时返回非零。这是 UNIX 和 DOS 脚本使用的标准,用于找出您的程序发生了什么。

回答by Jeegar Patel

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

main()在 C89 和 K&R C 中,未指定的返回类型默认为“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 0or return 1will 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().

  1. 如果没有在 中写入 return 语句int main(){默认情况下关闭将返回 0。

  2. return 0return 1将被父进程接收。在 shell 中,它进入一个 shell 变量,如果您正在从 shell 运行程序而不使用该变量,那么您不必担心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().

通过这种方式,您可以看到它是$?接收 的返回值的最低有效字节的变量main()

In Unix and DOS scripting, return 0on 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.

在 Unix 和 DOS 脚本中,return 0通常返回成功和非零错误。这是 Unix 和 DOS 脚本使用的标准,用于找出您的程序发生了什么并控制整个流程。

回答by Ferruccio

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

请记住,即使您返回的是 int,某些操作系统 (Windows) 也会将返回值截断为单个字节 (0-255)。

回答by Yochai Timmer

The return value can be used by the operating system to check how the program was closed.

操作系统可以使用返回值来检查程序是如何关闭的。

Return value 0 usually means OK in most operating systems (the ones I can think of anyway).

返回值 0 通常意味着在大多数操作系统中都可以(无论如何我都能想到)。

It also can be checked when you call a process yourself, and see if the program exited and finished properly.

当您自己调用进程时也可以检查它,并查看程序是否正确退出和完成。

It's NOTjust a programming convention.

这是不是只是一个编程约定。

回答by fuddin

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

的返回值main()显示程序如何退出。如果返回值是,zero则表示执行成功,而任何非零值都表示执行中出现问题。