22

I see in a lot of legacy software and bad tutorials on the Internet that recommend using exit(-1), return -1 or similar to represent "abnormal termination". The problem is, in POSIX at least, -1 has never been and is not a valid status code. man 3 exit illustrates that exit() returns the value of status & 0377 to the parent, meaning that -1 becomes 255. On non-POSIX systems, EXIT_FAILURE is recommended for portability. But I never see "-1 means abnormal termination" in conjunction with "EXIT_FAILURE may be something other than 1", indicating that they clearly believe "-1" is conventional even on non-POSIX systems.

Here's an example of a StackOverflow question that perpetuates this. The software "unrealircd" is also an example of a program that uses exit(-1) to terminate the program. In practice, this makes it difficult to interface with systemd.

Where did this anti-pattern come from? Is it valid in some context?

20

Almost all Unix computers use twos-complement for integers, and in twos-complement -1 is always "all bits 1" regardless of the word size. If you want the largest possible exit code regardless of the size of the program's exit status, using -1 and letting the library truncate it conveniently does the trick.

That's useful because when scripts or programs have more than one possible exit status (see grep for a simple example) the meaningful ones are usually assigned to the smallest numbers, making the largest possible exit code a good one to use for "unknown error" or "abort" since it's unlikely to ever conflict with a meaningful status value.

  • Take glibc as an example, which implements exit() as status &= 0xff. Is there a "word size" in which -1 & 0xff is not 255? Of course not, because the whole purpose is to make it fit in the range of 0-255. Regardless, your last sentence doesn't make sense: status codes 128-255 do have special purpose in UNIX systems. – user222973 Apr 2 '16 at 21:43
  • 2
    Don't confuse Bash exit values (which are 0-127, 128+ being special Bash values) with program exit values (which are 0-255, see pubs.opengroup.org/onlinepubs/009695399/functions/exit.html). As for the size, remember that C programmers have been dealing with multiple word sizes (originally 12, 16, and 32 bits) since the beginning so we automatically try for idioms that don't require us to consider word size. Since Unix predates Posix by 2 decades there wasn't always the 8-bit limitation so we wrote so it didn't matter. – Todd Knarr Apr 3 '16 at 2:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.