关于 C/C++ 的 main 函数
下面文字引自:http://prinse.blog.
C语言为了产生高效率可执行代码的原因,将许多权利(当然也就要求相应的义务)交给实现和程序员,因而在相应的标准中并不做规定,这就产生许多“未定义” 行为。void mian() {...} 的写法也不见得是一种“错误”!Bjarne Stroustrup说过:The definition
void main() { /* ... */ }
is not and never has been C++, nor has it even been C.
他甚至更为严厉地指出:A [bo]conforming implementation [/bo]accepts
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
A [bo]conforming implementation [/bo]may provide more versions of main(), [bo]
but they must all have return type int[/bo].
我的理解是 void main() {...} 这种写法无论是在C++ 还是 C 的标准文本中从来就没有明确说过!的确,标准文本中从来就没有出现过这种版本的sample。不过,标准文本中似乎也从来没有明确说过这是错误的用法!在 C 的标准文本中对于 main 函数一般是这么说的:
The function called at program startup is named main. The implementation declares no prototype for this function. It [bo]
shall [/bo]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; or in some other implementation-defined manner.
文本的意图非常明显:一个程序应该与它所依赖的运行环境至少有一种简洁交互。然而,标准文本并不明确反对应用程序不与环境交互!如果留意标准文本中接下来的对于 main 的返回值的说明,我想应该对此有所帮助:
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;10) reaching the } that terminates the main function returns a value of 0. [bo]
If the return type is not compatible with int,
the termination status returned to the host environment is unspecified[/bo].
注意最后一句!文本指出:如果 main 的返回类型与 int 不相容,那么程序给环境的结束返回状态是“unspecified”的,或者理解为“不明确”的!
C++ 对于 main 的说明也是意图一致的:
A program [bo]shall [/bo]contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function. [Note: in a freestanding environment, start-up and termination is implementation-defined; startup contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration. ]
An implementation shall not predefine the main function. This function shall not be overloaded. It [bo]shall [/bo]have a return type of type int, [bo]
but otherwise its type is implementation-defined[/bo]. All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
注意,标准文本中对此使用的情态动词是“shall”而不是带有强制性的“must”,它明显是一种“建议”,而不是“必须遵守的规定”!
显然,C/C++ 在这里把对 main 函数的参数和返回类型的规定交给了实现!但是,同时 C/C++ 都要求各个实现必须至少支持 main 函数的上述两种规定!早期为 C 语言在 PC 上推广立下汗马功劳的 Turbo C 就支持
void main() {...}
的用法,Microsoft MSC 和现在的 Visual C/C++ 也还支持这种用法。GCC 的 C 和 C++ 实现在 UNIX 系统上还支持
int main (int argc, char *argv[], char *envp[]) {...}
的“三参数”格式。这些都证明 C/C++ 标准文本对 main 函数的格式并不做明确规定(C/C++的本意也不愿意这么做)!所以讨论 void main() 格式是否是错误这样的命题本来就是伪命题!我们只能说这种格式在某些实现中是被支持的,而在另外一些实现中是不被支持的。有一点可以明确的是: Bjarne Stroustrup 是
坚决反对这种用法的!
话说回来,void main() 这种格式确实不是一种良好的编程风格。虽然笔者比较孤陋寡闻,不过也用过那么一些 C/C++ 编译器。就笔者用过的编译器而言,很多现代 C/C++ 编译器都不大愿意支持这种格式!因此,不管是出于什么原因,程序员最好还是接受 C/C++ 标准文本所建议那两种明示的 main 函数格式。
以上仅为一家之言,有不妥之处,欢迎指出!
注:文中引用的文字出自
[1]. ISO/IEC 9899:1999 (E),INTERNATIONAL STANDARD ISO/IEC9899 Second edition,Programming languages — C,1999-12-01
[2]. ISO/IEC 14882:2003(E),INTERNATIONAL STANDARD ISO/IEC14882 Second edition,Programming languages — C++,2003-10-15
[3]. S.Loosemore, R.M.Stallman, R.McGrath, A.Oram, U.Drepper,The GNU C Library Reference Manual,Edition 0.11(last updated 2006-12-03 for version 2.6)
[4]. Bjarne Stroustrup's homepage,http://www.research.
[[it] 本帖最后由 prinse 于 2008-4-9 15:54 编辑 [/it]]