我开始使用以下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" ?
答案 0 :(得分:4)
如果main
的返回类型不是int
或某些实现定义的类型(其中"实现定义"表示它已记录通过实现),行为未定义。
这意味着编译器不需要发出警告或错误消息,但C标准说 nothing 关于程序的行为方式。
实际行为取决于编译器(调用约定等)和操作系统。
在许多情况下,main
(如果有)返回的值只会被解释为int
。如果它返回值为double
的{{1}},则可能等同于返回1.0
值1065353216。
或者编译器可能在编译时拒绝它。或者你的程序可能崩溃。就C标准而言,字面上任何都可能发生。
C中存在大量编码错误,编译器无需以任何特定方式检测或处理。在这种情况下,完全由程序员来决定是否正确。
只需使用正确的声明即可。对于托管实现,请使用
int
或
int main(void) { /* ... */ }
(对于独立(嵌入)实现,声明完全是实现定义的,入口点可能会或可能不会被称为int main(int argc, char *argv[]) { /* ... */ }
;请参阅编译器的文档。)
至于为什么宣布main
错误地不需要诊断,我并不完全确定。它确实使编译器编写者的操作稍微简单一些。他们可以像对待任何其他功能一样对待main
。 一些非标准形式实际上是有用的;例如,类UNIX系统有时允许
main
其中第三个参数提供对环境变量的访问。如果必须诊断出int main(int argc, char *argv[], char *envp) { /* ... */ }
的错误定义,我个人会更喜欢它。
这也在comp.lang.c FAQ中讨论,从问题11.12a开始。
答案 1 :(得分:0)
操作系统需要int
类型的返回值,并从默认位置获取(例如,注册EAX
)。如果返回其他类型,操作系统将再次获得EAX
的值。没什么特别的。