如果main()没有返回int值会发生什么?

我知道在C编译器中, main()函数由_start()函数调用,该_start()代码如下:

 exit(main()); // return value of main is returned 

main()不返回int_start()如何工作,例如,如果返回类型为voidfloat或其他什么?

如果main没有返回int ,那么你有一个格式错误的程序,并且行为未定义。 任何事情都可能发生。 您的程序可能会崩溃,或者它可能会运行,好像没有任何错误。

假设main返回了除int其他内容,并且您的编译器和链接器允许编写程序。 但是,来电者并不知道这一点。 如果调用者期望在EAX(Intel)寄存器中返回返回的int值,那么它将读取以确定main的返回值。 如果你的错误main存储了一个float值,那么它将被解释为一个int 。 (这并不意味着它会被截断。这意味着构成浮点值布局的位将改为构成一个int 。)如果你的错误main返回void ,那么它没有存储任何东西。预期的寄存器,因此调用者将获得之前存储在该寄存器中的任何值。

如果你的main返回某些类型,它希望存储一个调用者没有为其保留内存的地方(例如一个大型结构),那么它最终将覆盖其他东西,这可能对程序的干净关闭很重要,导致程序崩溃。

C标准从未提到过这个_start函数; 我不相信C ++也会这样做。

在1999 ISO标准之前的C中,如果执行到达main()的末尾而不执行return语句,或执行未指定值的return语句,则“返回到主机环境的终止状态未定义” 。 在实践中,我已经看到这样的程序返回状态为1(失败)的实现,或者内存中的某些任意值,例如被调用的最后一个函数的结果。

1999 ISO C标准改变了这一点:“到达},终止函数返回值0”。 这符合C ++至少自1998年第一个ISO C ++标准以来的规则。

(作为一种风格,我更喜欢有一个明确的return 0;main的末尾,即使它不是严格要求的。这与除main之外的int函数一致,并且它使得更好的可移植性到C99之前的C编译器。)

所有这些都假设main是使用返回类型int定义的。 这是C标准特别支持的唯一类型( int main(void)int main(int argc, char *argv[])或等效),但(托管)实现可能支持其他实现定义的定义。 C90标准没有明确涵盖这种情况,但C99说,“如果返回类型与int不兼容,则返回到主机环境的终止状态未指定。”

C ++标准有点不同。 对于托管实现, 必须定义main以返回int 。 参数是实现定义的,但必须支持C的标准forms。

对于C或C ++中的托管实现,我知道使用除int之外的返回类型定义main是没有充分理由的。 只需使用两个标准定义中的一个,就不会出现问题。

对于“独立实现”,“在程序启动时调用的函数的名称和类型是实现定义的”。 因此,入口点可能合法地返回void或其他内容,甚至可能不会被称为main 。 注意,“独立实现”是“其中C程序执行可以在没有操作系统的任何益处的情况下发生”,通常是嵌入式系统。

该函数将返回实现定义的值。 例如,在C ++中, main隐式返回0 。 在这个void main的情况下,这将简单地由_start返回。 但是,几乎没有任何实现可以允许任何任意返回类型 – 它被烘焙到操作系统中,进程以整数值退出。

在C ++中,从main()返回除int之外的任何内容将是一个编译错误:

 error: '::main' must return 'int' 

在C中它是一个警告,你将得到一个浮动重新解释为int :例如,2.1F将被重新解释为224。

C的标准实现期望main返回int只是因为它在C标准中以这种方式定义。 返回int以外的东西(或与int兼容的类型)通常会导致未定义的行为 – 这意味着没有办法告诉将会发生什么。

但是,有非标准的C实现,例如,Plan 9操作系统使用void main() , 这里列出了它们的实用程序的源代码。 Plan 9 C代码与K&R,ANSI,C99或C11完全不同。 这是一个解释Plan 9如何使用C语言的链接。

如果main的返回类型不是int则返回值是实现定义的。
简而言之,允许实现具有与main不同的返回类型,但是没有任何已知实现支持除int之外的任何其他实现。
理想情况下,您需要参考平台和编译器的文档,以了解它定义的确切行为,因为标准允许它具有灵活性。

参考:

C ++ 03标准:

3.6.1主要function[basic.start.main]

实现不应预定义主要function。 此function不应超载。 它应具有int类型的返回类型,否则其类型是实现定义的 。 所有实现都应允许以下两个主要定义:

int main(){/ * … * /}

int main(int argc,char * argv []){/ * … * /}

…..

C标准不允许您返回除int 或void之外的任何其他值–c编译器专门测试main的签名以确保它是兼容的。

假设我们正在使用Visual Studio 2012。

对于C ++程序,Visual Studio允许将void指定为返回类型,即使这是C ++标准禁止的。 在标准下, main()必须在托管实现中返回一个int

对于C程序, main()允许任何返回类型,但返回int以外的其他内容会导致未指定的行为。 例如,在Visual Studio 2012下,当在调试器中运行程序时,从double main()返回0.0导致返回值为0xcccccccc (请参阅在Visual Studio C ++中,内存分配表示是什么? )。