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
What should main() return in C and C++?
提问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 1
or return 0
?
main()
在 C 和 C++ 中定义函数的正确(最有效)方法是什么——int main()
或者void main()
——为什么?如果int main()
然后return 1
或return 0
?
There are numerous duplicates of this question, including:
这个问题有很多重复,包括:
- What are the valid signatures for C's
main()
function? - The return type of
main()
function - Difference between
void main()
andint main()
? main()
's signature in C++- What is the proper declaration of
main()
?— For C++, with a very good answer indeed. - Styles of
main()
functions in C - Return type of
main()
method in C int main()
vsvoid main()
in C
- C
main()
函数的有效签名是什么? main()
函数的返回类型void main()
和之间的区别int main()
?main()
C++ 中的签名- 什么是正确的声明
main()
?— 对于 C++,确实有很好的答案。 main()
C 中的函数样式main()
C中方法的返回类型int main()
与void main()
C 中的比较
Related:
有关的:
- C++ —
int main(int argc, char **argv)
- C++ —
int main(int argc, char *argv[])
- Is
char *envp[]
as a third argument tomain()
portable? - Must the
int main()
function return a value in all compilers? - Why is the type of the
main()
function in C and C++ left to the user to define? - Why does
int main(){}
compile? - Legal definitions of
main()
in C++14?
采纳答案by workmad3
The return value for main
indicates 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++ main
signatures 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 main
function. 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 int
return 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): 0
and EXIT_SUCCESS
for a successful termination, and EXIT_FAILURE
for an unsuccessful termination. Any other values are non-standard and implementation defined. main()
must have an explicit return
statement at the end to avoid undefined behaviour.
该标准定义了用于返回严格遵循(即不依赖于实现定义的行为)3个值:0
和EXIT_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
int
return type may not be omitted. - You may omit the return statement from
main()
. If you do, andmain()
finished, there is an implicitreturn 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 ofint
and with no parameters:int main(void) { /* ... */ }
or with two parameters (referred to here as
argc
andargv
, 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
argc
shall be nonnegative.argv[argc]
shall be a null pointer.- If the value of
argc
is greater than zero, the array membersargv[0]
throughargv[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
argc
is greater than zero, the string pointed to byargv[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 ofargc
is greater than one, the strings pointed to byargv[1]
throughargv[argc-1]
represent the program parameters.- The parameters
argc
andargv
and the strings pointed to by theargv
array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.10)Thus,
int
can be replaced by a typedef name defined asint
, or the type ofargv
can be written aschar **argv
, and so on.
5.1.2.2.1 程序启动
程序启动时调用的函数名为
main
. 实现声明没有此函数的原型。它应定义为返回类型int
并且不带参数:int main(void) { /* ... */ }
或带有两个参数(这里称为
argc
andargv
,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):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]
表示程序参数。- 数组指向的参数
argc
和argv
字符串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
main
function is a type compatible withint
, a return from the initial call to themain
function is equivalent to calling theexit
function with the value returned by themain
function as its argument;11)reaching the}
that terminates themain
function returns a value of 0. If the return type is not compatible withint
, 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
main
will 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 0
is mandated as 'success'. You can use EXIT_FAILURE
and EXIT_SUCCESS
from <stdlib.h>
if you prefer, but 0 is well established, and so is 1. See also Exit codes greater than 255 — possible?.
请注意,这0
被要求为“成功”。如果您愿意,您可以使用EXIT_FAILURE
and EXIT_SUCCESS
from <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
exit
function?5 Finally, control is returned to the host environment. If the value of
status
is zero orEXIT_SUCCESS
, an implementation-defined form of the status successful terminationis returned. If the value ofstatus
isEXIT_FAILURE
, an implementation-defined form of the status unsuccessful terminationis returned. Otherwise the status returned is implementation-defined.
7.22.4.4
exit
功能?5 最后,控制权返回到宿主环境。如果 的值
status
为零或EXIT_SUCCESS
,则返回状态成功终止的实现定义形式。如果值status
是EXIT_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
argc
shall be the number of arguments passed to the program from the environment in which the program is run. Ifargc
is nonzero these arguments shall be supplied inargv[0]
throughargv[argc-1]
as pointers to the initial characters of null-terminated multibyte strings (NTMBSs) (17.5.2.1.4.2) andargv[0]
shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or""
. The value ofargc
shall be non-negative. The value ofargv[argc]
shall be 0. [ Note: It is recommended that any further (optional) parameters be added afterargv
. —end note ]?3 The function
main
shall not be used within a program. The linkage (3.5) ofmain
is 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::exit
with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executingreturn 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 exit
functionin the C11 standard (quoted above), apart from a footnote (which simply documents that EXIT_SUCCESS
and EXIT_FAILURE
are defined in <cstdlib>
).
C++11 标准中有一段 §18.5开始和终止与 §7.22.4.4 C11 标准中的exit
函数(上面引用的)相同,除了脚注(它只是记录EXIT_SUCCESS
和EXIT_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 tochar
, 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
main
andwmain
functions can be declared as returningvoid
(no return value). If you declaremain
orwmain
as 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 whenmain
orwmain
is declared asvoid
, you must use theexit
function.
main 的声明语法是
int main();
或者,可选地,
int main(int argc, char *argv[], char *envp[]);
或者,
main
和wmain
函数可以声明为返回void
(无返回值)。如果声明main
或wmain
返回 void,则不能使用 return 语句将退出代码返回给父进程或操作系统。要在main
或wmain
声明为时返回退出代码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 main
and 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 functionsabort
,atexit
,at_quick_exit
,exit
, andquick_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>
应宣布至少功能abort
,atexit
,at_quick_exit
,exit
,和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
sizeof
and_Alignof
operators…
?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.4
sizeof
和_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_SUCCESS
or EXIT_FAILURE
. They are defined in stdlib.h
我相信main()
应该返回EXIT_SUCCESS
或EXIT_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 toint main
4.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 main
4 的附加参数。然而,托管环境程序终止部分继续争论 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
参考
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[]) { /* ... */ }
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.
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.
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.).
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.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.
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.
ISO 9899:1999 5.1.2.1 Freestanding environment
This section is identical to the C99 one cited above.
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[]) { /* ... */ }
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.
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).
ISO 14882:2011 3.6.1 Main function
This section is identical to the C++03 one cited above.
ANSI X3.159-1989 2.1.2.2 托管环境。“程序启动”
程序启动时调用的函数名为 main。实现声明没有此函数的原型。它应定义为返回类型为 int 且不带参数:
int main(void) { /* ... */ }
或带有两个参数(此处称为 argc 和 argv,尽管可以使用任何名称,因为它们对于声明它们的函数而言是本地的):
int main(int argc, char *argv[]) { /* ... */ }
ANSI X3.159-1989 2.1.2.1 独立环境:
在独立环境中(在这种环境中,C 程序可以在没有任何操作系统优势的情况下执行),程序启动时调用的函数的名称和类型是实现定义的。
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) 或以其他一些实现定义的方式。
国际标准的基本原理 — 编程语言 — 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.)。
ISO 9899:1999 5.1.2.2 托管环境 --> 5.1.2.2.3 程序终止
如果 main 函数的返回类型是与 int 兼容的类型,则从初始调用 main 函数的返回相当于以 main 函数返回的值作为参数调用 exit 函数;11) 到达
}
终止main 函数返回值 0。如果返回类型与 int 不兼容,则返回给宿主环境的终止状态是未指定的。ISO 9899:1999 5.1.2.1 独立环境
在独立环境中(在这种环境中,C 程序可以在没有任何操作系统优势的情况下执行),程序启动时调用的函数的名称和类型是实现定义的。
ISO 9899:2011 5.1.2.2 托管环境 -> 5.1.2.2.1 程序启动
本节与上面引用的 C99 相同。
ISO 9899:1999 5.1.2.1 独立环境
本节与上面引用的 C99 相同。
ISO 14882:2003 3.6.1 主要功能
实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许以下两个 main 定义:
int main() { /* ... */ }
和
int main(int argc, char* argv[]) { /* ... */ }
ISO 14882:2003 3.6.1 主要功能
独立环境中的程序是否需要定义主函数是实现定义的。
ISO 14882:2011 3.6.1 主要功能
实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许
— 一个 () 返回 int 和的函数
— 返回 int 的 (int, 指向指向 char 的指针的指针) 的函数
作为主要的类型(8.3.5)。
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?
If you do not write a return statement in
int main()
, the closing{
will return 0 by default.return 0
orreturn 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 ofmain()
.
如果没有在 中写入 return 语句
int main()
,{
默认情况下关闭将返回 0。return 0
或return 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 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.
在 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 zero
it means that the execution was successful while any non-zero value will represent that something went bad in the execution.
的返回值main()
显示程序如何退出。如果返回值是,zero
则表示执行成功,而任何非零值都表示执行中出现问题。