简体   繁体   English

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

[英]What happens if main() does not return an int value?

I know that in C compilers the main() function is called by the _start() function which has code something like this: 我知道在C编译器中, main()函数由_start()函数调用,该_start()代码如下:

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

How does _start() work when main() does not return int , for example if its return type is void , float , or something else? main()不返回int_start()如何工作,例如,如果返回类型为voidfloat或其他什么?

If main doesn't return int , then you have an ill-formed program and behavior is undefined. 如果main不返回int ,那么你有一个格式错误的程序,并且行为未定义。 Anything can happen. 任何事情都可能发生。 Your program might crash, or it might run as though nothing were wrong at all. 您的程序可能会崩溃,或者它可能会运行,好像没有任何错误。

Let's suppose main returned something other than int , and your compiler and linker allowed the program to be made. 假设main返回了除int其他内容,并且您的编译器和链接器允许编写程序。 The caller doesn't know that, though. 但是,来电者并不知道这一点。 If the caller expects returned int values to be returned in the EAX (Intel) register, then that's what it will read to determine the return value of main . 如果调用者期望在EAX(Intel)寄存器中返回返回的int值,那么它将读取以确定main的返回值。 If your faulty main stored a float value there, then it will be interpreted as an int instead. 如果你的错误main存储了一个float值,那么它将被解释为int (That doesn't mean it will get truncated. It means the bits making up the layout of a floating-point value will instead make up an int instead.) If your faulty main returned void , then it didn't store anything in the expected register, so the caller will get whatever value was previously stored in that register instead. (这并不意味着它会被截断。这意味着构成浮点值布局的位将改为构成一个int 。)如果你的错误main返回void ,那么它没有存储任何东西。预期的寄存器,因此调用者将获得之前存储在该寄存器中的任何值。

If your main returns some type that it expects to store someplace that the caller didn't' reserve memory for (such as a large struct), then it will end up overwriting something else, perhaps something important to the clean shutdown of the program, causing your program to crash. 如果你的main返回某些类型,它希望存储一个调用者没有为其保留内存的地方(例如一个大型结构),那么它最终将覆盖其他内容,这可能对程序的干净关闭很重要,导致程序崩溃。

The C standard never mentions this _start function; C标准从未提及过这个_start函数; I don't believe C++ does either. 我不相信C ++也会这样做。

In C prior to the 1999 ISO standard, if execution reaches the end of main() without executing a return statement, or executes a return statement that doesn't specify a value, then "the termination status returned to the host environment is undefined". 在1999 ISO标准之前的C中,如果执行到达main()的末尾而不执行return语句,或执行未指定值的return语句,则“返回到主机环境的终止状态未定义” 。 In practice, I've seen implementations where such a program returns a status of 1 (failure), or some arbitrary value in memory such as the result of the last function that was called. 在实践中,我已经看到这样的程序返回状态为1(失败)的实现,或者内存中的某些任意值,例如最后一个被调用函数的结果。

The 1999 ISO C standard changed this: "reaching the } that terminates the main function returns a value of 0". 1999 ISO C标准改变了这一点:“到达},终止函数返回值0”。 This matches the rule that C++ has had at least since the first ISO C++ standard in 1998. 这符合C ++至少自1998年第一个ISO C ++标准以来的规则。

(As a matter of style, I prefer to have an explicit return 0; at the end of main , even if it's not strictly required. This is consistent with int functions other than main , and it makes for better portability to pre-C99 C compilers.) (作为一种风格,我更喜欢有一个明确的return 0;main的末尾,即使它不是严格要求的。这与除main之外的int函数一致,并且它使得更好的可移植性到C99之前的C编译器。)

All this assumes that main is defined with a return type of int . 所有这些都假设main是使用返回类型int定义的。 That's the only type that's specifically supported by the C standard (either int main(void) or int main(int argc, char *argv[]) or equivalent), but (hosted) implementations may support other implementation-defined definitions. 这是C标准特别支持的唯一类型( int main(void)int main(int argc, char *argv[])或等效),但(托管)实现可能支持其他实现定义的定义。 The C90 standard doesn't explicitly cover this case, but C99 says, "If the return type is not compatible with int, the termination status returned to the host environment is unspecified." C90标准没有明确涵盖这种情况,但C99说,“如果返回类型与int不兼容,则返回到主机环境的终止状态未指定。”

The C++ standard is a bit different. C ++标准有点不同。 For hosted implementations, main must be defined to return int . 对于托管实现, 必须定义main以返回int The parameters are implementation-defined, but both the standard forms of C must be supported. 参数是实现定义的,但必须支持C的标准形式。

For a hosted implementation in either C or C++, there is no good reason I know of to define main with a return type other than int . 对于C或C ++中的托管实现,我没有充分理由使用除int之外的返回类型来定义main Just use one of the two standard definitions, and the question won't arise. 只需使用两个标准定义中的一个,就不会出现问题。

For "freestanding implementations", "the name and type of the function called at program startup are implementation-defined". 对于“独立实现”,“在程序启动时调用的函数的名称和类型是实现定义的”。 So the entry point might legitimately return void or something else, and it might not even be called main . 因此,入口点可能合法地返回void或其他内容,甚至可能不会被称为main Note that a "freestanding implementation" is one "in which C program execution may take place without any benefit of an operating system", typically an embedded system. 注意,“独立实现”是“其中C程序执行可以在没有操作系统的任何益处的情况下发生”,通常是嵌入式系统。

The function will return an implementation-defined value. 该函数将返回实现定义的值。 For example, in C++, main implicitly returns 0 . 例如,在C ++中, main隐式返回0 In this case of a void main then this would simply be returned by _start . 在这个void main的情况下,这将简单地由_start返回。 However, there are virtually no implementations that would allow any arbitrary return type- it's baked into the operating system that a process exits with an integral value. 但是,几乎没有任何实现可以允许任何返回类型 - 它被烘焙到操作系统中,进程以整数值退出。

In C++ it would be a compile error to return anything other than int from main() : 在C ++中,从main()返回除int之外的任何东西都是编译错误:

error: ‘::main’ must return ‘int’

In C it is a warning, you will get a float reinterpreted as an int : for example, 2.1F would be reinterpreted as 224. 在C中它是一个警告,你将得到一个浮动重新解释为int :例如,2.1F将被重新解释为224。

Standard implementations of C expect main to return int just because it is defined that way in the C standard. C的标准实现期望main返回int只是因为它在C标准中以这种方式定义。 Returning something other than int (or a type compatible with int ) usually results in undefined behaviour—meaning there is no way to tell what will happen. 返回int以外的东西(或与int兼容的类型)通常会导致未定义的行为 - 这意味着没有办法告诉将会发生什么。

However, there are non-standard implementations of C, for example, the Plan 9 operating system uses void main() , here is a list their utilities' source code. 但是,有非标准的C实现,例如,Plan 9操作系统使用void main()这里列出了它们的实用程序的源代码。 Plan 9 C code is quite a bit different to K&R, ANSI, C99 or C11. Plan 9 C代码与K&R,ANSI,C99或C11完全不同。 Here's a link explaining how Plan 9 uses the C language. 这是一个解释Plan 9如何使用C语言的链接。

If the return type of main is not an int then the return value is implementation defined. 如果main的返回类型不是int则返回值是实现定义的。
In short an Implementation is allowed to have different return type than int for main but none of the known implementations support anything other than int . 总之实现是允许有不同的返回类型不是intmain ,但没有一个已知的实现的支持比其他任何int
Ideally, You will need to refer to the documentation of your platform and the compiler to see what exact behavior it defines because it is allowed to have the flexibility do so by the standard. 理想情况下,您需要参考平台和编译器的文档,以了解它定义的确切行为,因为标准允许它具有灵活性。

Reference: 参考:

C++03 Standard: C ++ 03标准:

3.6.1 Main function [basic.start.main] 3.6.1主要功能[basic.start.main]

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 . 它应该具有int类型的返回类型,否则其类型是实现定义的 All implementations shall allow both of the following definitions of main: 所有实现都应允许以下两个主要定义:

int main() { /* ... */ } int main(){/ * ... * /}

and

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

..... .....

Assume we're using Visual Studio 2012. 假设我们正在使用Visual Studio 2012。

For C++ programs, Visual Studio allows void to be specified as the return type, even though this is forbidden by the C++ standard. 对于C ++程序,Visual Studio允许将void指定为返回类型,即使这是C ++标准禁止的。 Under the standard, main() must return an int in hosted implementations. 在标准下, main()必须在托管实现中返回一个int

For C programs, any return type is allowed for main() , but returning something other than an int results in unspecified behavior. 对于C程序, main()允许任何返回类型,但返回int以外的其他内容会导致未指定的行为。 For example, under Visual Studio 2012, returning 0.0 from double main() results in a return value of 0xcccccccc when the program is run in the debugger (see In Visual Studio C++, what are the memory allocation representations? ). 例如,在Visual Studio 2012下,当在调试器中运行程序时,从double main()返回0.0导致返回值为0xcccccccc (请参阅在Visual Studio C ++中,内存分配表示是什么? )。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM