Any benefit in using WEXITSTATUS macro in C over division by 256 on exit() status?

后端 未结 4 925
清酒与你
清酒与你 2020-12-03 05:48

I was doing an exercise for university where I had to return a value with exit, that value was actually a count of something. This could be above 255 (which exit() can\'t ha

相关标签:
4条回答
  • 2020-12-03 06:07

    And the real question in this topic, is the same thing to call this macro in my code as dividing by 256?

    It will probably always work in the cases where the child process terminates normally (i.e., by calling exit(), not by a segmentation fault, assertion failure, etc.).

    The status stored by waitpid() encodes both the reason that the child process was terminated and the exit code. The reason is stored in the least-significant byte (obtained by status & 0xff), and the exit code is stored in the next byte (masked by status & 0xff00 and extracted by WEXITSTATUS()). When the process terminates normally, the reason is 0 and so WEXITSTATUS is just equivalent to shifting by 8 (or dividing by 256). However, if the process is killed by a signal (such as SIGSEGV), there is no exit code, and you have to use WTERMSIG to extract the signal number from the reason byte.

    0 讨论(0)
  • 2020-12-03 06:13

    If the status variable is a signed 16-bit integer (a 'short') on a machine where 'int' is a 32-bit quantity, and if the exit status is in the range 128..255, then WEXITSTATUS() still gives you a correct value where dividing by 256 or simply shifting right will give you an incorrect value.

    This is because the short will be sign extended to 32-bits, and the masking undoes the the sign extension, leaving the correct (positive) value in the result.

    If the machine used 16-bit integers, then the code in WEXITSTATUS() would probably do shift then mask to ensure similar behaviour:

    #define WEXITSTATUS(status) (((status)>>8) & 0xFF)
    

    It is because the implementation takes care of such details for you that you should use the WEXITSTATUS() macro.

    0 讨论(0)
  • 2020-12-03 06:25

    As far as I can tell from checking the Single Unix Spec, your system happens to store the exit status in the second-to-rightmost octet, but I don't believe the standard does. So, you should use the macros for at least a few reasons:

    • They're correct. Bit-shifting a negative number does different things on different platforms. Does it work the way you want on yours? I don't know.
    • They're simple. Its immediately clear what WEXITSTATUS does. Less so with other approaches. If you saw the hand-rolled version of WIFSIGNALED, would you recognize it? How much longer would it take than WIFSIGNALED.
    • They're portable. Since its how the spec says to do it, it'll work on every system (at least pretty much every Unix-like system).
    0 讨论(0)
  • 2020-12-03 06:26

    Here 0xff00 is a binary mask (link text). ANDing it with a value sets all bits to zero, except the second byte (counting from the right).

    You should only use WEXITSTATUS on a process which is known to have exited normally. This information is given by the WIFEXITED macro.

    And the real question in this topic, is the same thing to call this macro in my code as dividing by 256?

    The macro makes the code more readable, and it's guaranted to work on any Posix-compliant implementation. As far as I know Posix doesn't specify the format of the status, so you can't expect your code to work everywhere.

    0 讨论(0)
提交回复
热议问题