C语言 C 的 main() 函数的有效签名是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2108192/
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 are the valid signatures for C's main() function?
提问by Prady
What really are the valid signatures for main function in C? I know:
C 中 main 函数的有效签名到底是什么?我知道:
int main(int argc, char *argv[])
Are there other valid ones?
还有其他有效的吗?
回答by paxdiablo
The C11standard explicitly mentions these two:
该C11标准明确提到了这两个:
int main(void);
int main(int argc, char* argv[]);
although it does mention the phrase "or equivalent" with the following footnote:
尽管它确实在以下脚注中提到了“或等效”一词:
Thus,
intcan be replaced by atypedefname defined asint, or the type ofargvcan be written aschar ** argv, and so on.
因此,
int可以用typedef定义为的名称代替int,或者argv可以将的类型写为char ** argv,依此类推。
In addition, it also provides for more (implementation-defined) possibilities.
此外,它还提供了更多(实现定义的)可能性。
The relevant text (section 5.1.2.2.1, but this particular aspect is unchanged from C99) states:
相关文本(部分5.1.2.2.1,但此特定方面与 保持不变C99)指出:
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 ofintand with no parameters:int main(void) { /* ... */ }or with two parameters (referred to here as
argcandargv, 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; or in some other implementation-defined manner.
If they are declared, the parameters to the
mainfunction 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 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
argcis 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 ofargcis greater than one, the strings pointed to byargv[1]throughargv[argc-1]represent the program parameters.The parameters
argcandargvand the strings pointed to by theargvarray shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
程序启动时调用的函数名为
main. 实现声明没有此函数的原型。它应定义为返回类型int并且不带参数:int main(void) { /* ... */ }或带有两个参数(这里称为
argcandargv,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):int main(int argc, char *argv[]) { /* ... */ }或同等学历; 或以其他一些实现定义的方式。
如果声明了它们,则
main函数的参数应遵守以下约束:
的值
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应可由程序修改,并在程序启动和程序终止之间保留其最后存储的值。
Note that this is for a hosted environment, the ones you normally see in C programs. A free-standing environment (such as an embedded system) is far less constrained, as stated in 5.1.2.1of that same standard:
请注意,这是针对托管环境,即您通常在 C 程序中看到的环境。独立环境(例如嵌入式系统)的约束要少得多,如同一5.1.2.1标准中所述:
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.
在独立环境中(在这种环境中,C 程序可以在没有操作系统任何好处的情况下执行),程序启动时调用的函数的名称和类型是实现定义的。除了第 4 条要求的最小集合之外,任何独立程序可用的库设施都是实现定义的。
回答by Jonathan Leffler
Standard C
标准C
For a hosted environment (that's the normal one), the C99 standard says:
对于托管环境(这是正常环境),C99 标准说:
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 ofintand with no parameters:int main(void) { /* ... */ }or with two parameters (referred to here as
argcandargv, 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.
9)Thus,
intcan be replaced by a typedef name defined asint, or the type ofargvcan be written aschar **argv, and so on.
5.1.2.2.1 程序启动
程序启动时调用的函数名为
main. 实现声明没有此函数的原型。它应定义为返回类型int并且不带参数:int main(void) { /* ... */ }或带有两个参数(这里称为
argcandargv,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):int main(int argc, char *argv[]) { /* ... */ }或同等学历; 9)或以其他一些实现定义的方式。
9)因此,
int可以用定义为 的 typedef 名称代替int,或者argv可以将的类型写为char **argv,依此类推。
The C11 and C18 standards say essentially the same as the C99 standard.
C11 和 C18 标准在本质上与 C99 标准相同。
Standard C++
标准 C++
The C++98 standard says:
C++98 标准说:
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[]) { /* ... */ }
3.6.1 主函数【basic.start.main】
1 程序应包含一个名为 main 的全局函数,它是程序的指定开始。[...]
2 实现不应预定义主函数。该函数不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许以下两个 main 定义:
int main() { /* ... */ }和
int main(int argc, char* argv[]) { /* ... */ }
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. So a 'void main()' is directly not allowed by the C++ standard, though there's nothing it can do to stop a non-standard conforming implementation from allowing alternatives (nor a standard conforming implementation from allowing alternatives as extensions to the standard).
C++ 标准明确规定“它 [主函数] 应具有 int 类型的返回类型,否则其类型是实现定义的”,并且需要与 C 标准相同的两个签名。因此,C++ 标准直接不允许“void main()”,尽管它无法阻止不符合标准的实现允许替代方案(也无法阻止符合标准的实现允许替代方案作为标准的扩展)。
The C++03, C++11, C++14, and C++17 standards say essentially the same as C++98.
C++03、C++11、C++14 和 C++17 标准在本质上与 C++98 相同。
Common Extension
通用扩展
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;'. For a long time, that did not have a header that declared it, but the POSIX 2008 standard now requires it to be declared in <unistd.h>.
第三个参数是一个以空字符结尾的字符串指针列表,每个字符串都是一个环境变量,它有一个名称、一个等号和一个值(可能为空)。如果您不使用它,您仍然可以通过“ extern char **environ;”获取环境。很长一段时间,它没有声明它的标头,但 POSIX 2008 标准现在要求它在<unistd.h>.
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
mainandwmainfunctions can be declared as returningvoid(no return value). If you declaremainorwmainas 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 whenmainorwmainis declared asvoid, you must use theexitfunction.
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 o/s) when a program with void main()does exit — and the MS web site is silent too.
我不清楚当一个程序void main()退出时会发生什么(返回给父级或 o/s 的退出代码是什么)——而且 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 VS 2005 version of this pagedoes not list void main()as an alternative. The versionsfrom Microsoft VS 2008 onwards do.
此页面的 Microsoft VS 2005 版本未void main()作为替代列出。Microsoft VS 2008 以后的版本都可以。
Is int main()the same as int main(void)?
是int main()一样的int main(void)吗?
For a detailed analysis, see the end of my answer to What should main()return in C and C++. (It seems that I once considered that this question referred to C++, even though it doesn't and never did. In C++, there is no difference between int main()and int main(void)and int main()is idiomatic C++.)
有关详细分析,请参阅我对What should main()return in C and C++ 的回答的结尾。(似乎我曾经认为这个问题指的是 C++,尽管它没有也从来没有。在 C++ 中,int main()andint main(void)和 andint main()是惯用的 C++没有区别。)
In C, there is a difference between the two notations, but you only notice it in esoteric cases. Specifically, there's a difference if you call the main()function from your own code, which you'e allowed to do in C and are not allowed to do in C++.
在 C 中,这两种符号之间存在差异,但您只会在深奥的情况下注意到它。具体来说,如果您main()从自己的代码中调用该函数是有区别的,您可以在 C 中这样做,而在 C++ 中则不允许这样做。
The int main()notation does not provide a prototype for main(), but that only matters if you call it recursively. With int main(), you might later (in the same function, or in another function) write int rc = main("absolute", "twaddle", 2):and formally the compiler shouldn't complain to the extent of refusing to compile the code, though it might legitimately complain (warn you) about it (and using -Werrorwith GCC would convert the warning into an error). If you use int main(void), the subsequent call to main()should generate an error — you said the function takes no arguments but tried to provide three. Of course, you can't legitimately call main()before you've declared or defined it (unless you are still using C90 semantics) — and the implementation does not declare a prototype for main(). NB: The C11 standard illustrates both int main()and int main(void)in different examples — both are valid in C, even though there's the subtle difference between them.
该int main()表示法不提供 的原型main(),但仅当您递归调用它时才重要。使用int main(),您可能稍后(在同一个函数或另一个函数中)编写int rc = main("absolute", "twaddle", 2):并且正式地编译器不应该抱怨拒绝编译代码的程度,尽管它可能会合法地抱怨(警告您)(并使用-Werrorwith GCC 会将警告转换为错误)。如果你使用int main(void),随后的 调用main()应该会产生一个错误——你说这个函数不接受参数,但试图提供三个参数。当然,您不能main()在声明或定义它之前合法地调用(除非您仍在使用 C90 语义)——并且实现没有声明原型main(). 注:该C11标准的说明都int main()与int main(void)不同的实例-无论是在C时有效,即使它们之间的细微差别。
回答by unwind
回答by kennytm
http://en.wikipedia.org/wiki/Main_function_(programming)#C_and_C.2B.2B
http://en.wikipedia.org/wiki/Main_function_(编程)#C_and_C.2B.2B
Besides the usual int main(int argc, char *argv[])and the POSIX int main(int argc, char **argv, char **envp), on Mac OS X also supports
除了通常的int main(int argc, char *argv[])和 POSIX int main(int argc, char **argv, char **envp),在 Mac OS X 上也支持
int main(int argc, char* argv[], char* envp[], char* apple[]);
Of course it's Mac-only.
当然,它仅限于 Mac。
On Windows there's
在 Windows 上有
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);
as the Unicode (actually, wide-character) variant. Of course there is WinMaintoo.
作为 Unicode(实际上是宽字符)变体。当然也有WinMain。
回答by flashnik
int main(void)
Under some OS (for example, Windows) also such is valid:
在某些操作系统(例如,Windows)下也是有效的:
int main(int argc, char **argv, char **envp)
where envpgives an environment, otherwise accessible through getenv()
whereenvp给出一个环境,否则可以通过getenv()

