我开始用main()
的以下定义进行编程
void main(){}
然后有人告诉我,main((的这种格式是糟糕的编程,因为它应该返回int。他还告诉我,下面的main((定义在C.中是有效的
int main(void){}
或
int main(int argc,int *argv[]){}
今天,我尝试使用其他数据类型进行实验,令人惊讶的是,下面的所有编译都没有出错。
char main(){}
float main(){}
int* main(){}
即使这样也能成功编译
struct Abc{
int a;
};
struct Abc* main(){}
因此,我对此的问题如下:
操作系统如何处理这些意外的返回类型?[我这么问是因为我认为操作系统使用了
main()
的返回值]为什么允许
main()
返回任何类型?为什么编译器设计人员说"
main()
应该返回int">这样做如此灵活我认为如果他们说main()
必须返回int">就没有问题了?
如果main
的返回类型不是int
或某个实现定义的类型(其中"实现定义的"意味着它是由实现记录的(,则行为是未定义的。
这意味着编译器不需要发出警告或错误消息,但C标准对程序的行为没有任何规定。
实际行为取决于编译器(调用约定等(和操作系统。
在许多情况下,main
返回的值(如果有的话(将被简单地解释为int
。如果返回值为1.0
的double
,则可能等于返回值为1065353216的int
。
或者编译器可能会在编译时拒绝它。或者你的程序可能会崩溃。就C标准而言,任何的事情都可能发生。
C中有很多编码错误,编译器不需要检测或以任何特定的方式处理。在这种情况下,把事情做好完全取决于程序员。
只要使用正确的声明即可。对于托管实现,请使用
int main(void) { /* ... */ }
或
int main(int argc, char *argv[]) { /* ... */ }
(对于独立(嵌入式(实现,声明完全由实现定义,入口点可能被称为main
,也可能不被称为;请参阅编译器文档。(
至于为什么错误地声明main
不需要诊断,我不完全确定。它确实使编译器编写者的工作稍微简单一些。它们可以像对待任何其他功能一样对待CCD_ 15。有些非标准形式实际上很有用;例如,类UNIX系统有时允许
int main(int argc, char *argv[], char *envp) { /* ... */ }
其中第三个参数提供对环境变量的访问。如果必须诊断main
的定义不正确,我个人更愿意这样做。
这也在comp.lang.cFAQ中进行了讨论,从问题11.12a开始。
操作系统期望返回类型为int
的值,并从默认位置获取该值(例如寄存器EAX
(。如果您返回其他类型,操作系统将再次获得EAX
的值。没什么特别的。