Where did “exit(-1)” come from

anti-patternschistoryprogramming practices

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?

Best Answer

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.