简体   繁体   中英

Why are EXIT_SUCCESS and EXIT_FAILURE "implementation defined"?

If you are supposed to return 0 from main, and EXIT_SUCCESS is "implementation defined", and it literally says that it is not required to be 0 , then what is the point of it if you can't rely on it being the correct value? Am I missing something?

Returning the integer n from main (if main has an int return value) is equivalent to calling exit(n) -- 5.1.2.2.3.1 in the standard. exit is defined such that both exit(0) and exit(EXIT_SUCCESS) are both implementation-defined forms of the status successful termination -- 7.20.4.3.5 in the standard.

So returning 0 (or having no return and dropping off the end of main) cause a "successful" termination of a program.

I don't think the standard guarantees that return EXIT_SUCCESS and return 0 are exactly equivalent as returns from main, but it's definitely ok to return 0 from main and expect your OS to treat this as a successful termination of your program, no matter what EXIT_SUCCESS is defined as.

Note that websites like cppreference.com are not the best source of information about the C standard, even if they're mostly accurate -- it's much better to go to the actual standard (or at least one of the freely available committee drafts if the official standard is paywalled) and read what it says.

I believe this is a piece of retro-fitted standardisation.

At point of Standardisation (and EXIT_SUCCESS was defined then) it makes sense to permit the common practice ( return 0; ) but also to have constants and unnecessary to define that the constant is necessarily the common value. Though it usually is.

Having constants is well-aligned to a specific aim of Standardisation which was to make it possible to write portable C programs more easily.

Both 0 and EXIT_SUCCESS indicate successful program execution to the host environment. Though EXIT_SUCCESS is not required to be zero.

So it's wrong to say you can't rely in it being the correct value because it is guaranteed to be one of the correct values for indicating successful execution.

One of the one or more correct values at least one being 0 . I'm not aware of any platform where it isn't 0 .

Remember C had diversified onto a number of platforms when it was finally Standardised and by then almost universal practice was that the return value of 0 meant success following the convention that return codes are error-codes and 0 being logical 'false' means 'no error'.

However given the aim of Standardisation was to increase portability it makes sense to provide for implementation defined constants in a critical step of interaction with the host-environment - termination.

I don't know if the constants were introduced during standardisation or included from a contributing implementation.

Remember it's not defined what the Host Environment does with the return value. Yes, common practice is that it's value is returned to the script or process that initiated program execution. But it could be mapped. On a hosting platform that didn't use 0 for success that return value would have to be mapped to different value, quite possibly whatever EXIT_SUCCESS expands to.

It's a bit esoteric because I'm not aware of a platform where EXIT_SUCCESS isn't 0 but the committee was right that you can be have a well defined language by specifying behaviour not concrete value here.

You are supposed to return 0 on UNIXy systems, sure.

Consider targeting an esoteric OS where successful return code is, say, 42, and errors are 222.

That OS's headers will define those constants to 42 and 222, and your program, correctly using EXIT_SUCCESS , won't return zero, a completely weird value to the esoteric OS.

As an additional data point, eg FreeBSD defines a variety of other exit codes in sysexits.h .

If you are supposed to return 0 from main, and EXIT_SUCCESS is "implementation defined", and it literally says that it is not required to be 0, then what is the point of it if you can't rely on it being the correct value? Am I missing something?

You are missing the fact that more than one value can indicate a successful exit. A C implementation could define any non-negative value to indicate success, and it could define EXIT_SUCCESS to be 1.

it literally says that it is not required to be 0,

It literally says that because it depends on the operating system you are running on. Some operating systems have different termination codes to be sent to the parent process in case of failure, so something that is operating system dependent cannot be ensured by a standard document.

On the other side, you can implement a command that returns 1 on success and 0 when it fails. In that case you will receive (in linux/unix/posix) EXIT_SUCCESS when the program accually runs unsuccessfully, and EXIT_FAILURE when the program runs ok. It is a convention, and as such, someones can follow it and someones cannot. The C definition cannot state successfully that a program that returns successfully will do an exit(0); to indicate that to the caller program and exit(1); otherwise.

If you are supposed to return 0 from main, and EXIT_SUCCESS is "implementation defined", and it literally says that it is not required to be 0, then what is the point of it if you can't rely on it being the correct value?

You are in no way required to return 0 from the initial call to main() , nor (equivalently) to call exit(0) . If you terminate that way then the execution environment will be notified that the termination was successful, by that program's measure of success. As a separate matter , if you terminate by returning EXIT_SUCCESS from the initial call to main() or by calling exit(EXIT_SUCCESS) then in that case too, the execution environment will be notified that the termination was successful, regardless of the value to which EXIT_SUCCESS expands.

Am I missing something?

You are missing at least that

  • You can rely on a conforming C implementation to behave the way the spec says it does.

  • From the perspective of the language spec, the consumer of the program's exit code is the C language implementation, not the execution environment. It is C's responsibility to respond to the program's exit code in a manner appropriate to its execution environment.

  • there may be more than one exit code that indicates success to a particular C implementation. On the flip side, the significance of exit codes other than 0, EXIT_SUCCESS , and EXIT_FAILURE is not defined by C: such codes are not required (by C) to indicate failure conditions.

For all of those reasons, your conclusion that "you can't rely on [ EXIT_SUCCESS ] being the correct value" is completely unfounded. On the contrary, you absolutely can rely on EXIT_SUCCESS being a correct value.

I suspect that your view is being influenced by details of particular C implementations and host environments with which you are familiar. To understand C (or any programming language) semantics, it helps to distinguish carefully between the requirements and behavioral guarantees of the language itself on one hand, and those of the execution environment on the other. For one thing, your programs' portability is improved by relying only on the former inasmuch as that is possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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