【问题标题】:Any benefit in using WEXITSTATUS macro in C over division by 256 on exit() status?在 C 中使用 WEXITSTATUS 宏而不是在 exit() 状态下除以 256 有什么好处?
【发布时间】:2010-10-22 22:52:47
【问题描述】:

我正在为大学做一个练习,我必须在退出时返回一个值,该值实际上是一些东西的计数。这可能高于 255(exit() 无法处理),但老师建议使用计数永远不会超过该值的测试数据。

毕竟,我需要处理这个计数值,退出状态,我在主进程中使用waitpid()得到了这个值。令我惊讶的是,如果子进程返回 1,则主进程中的“真实”值是 256,2 是 512,依此类推……

我需要打印这个值,所以我简单地将它除以 256 就完成了。但是,如果我使用 WEXITSTATUS() 宏,我也会以我想要的方式获得这个值...

我查看了 C 源代码,这是我发现的:

#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)

我明白这里发生了什么,例如,二进制的 512 是 10 0000 0000,向右移动 8 位将得到 00 0000 0010,即十进制的 2。我在这个宏中不明白的是 & 运算符以及 0xff00 似乎是一个随机数的事实(它可能不是,它来自哪里?)。这到底是做什么的,为什么宏中有“& 0xff00”?没有它就不行吗?

这个主题的真正问题是,在我的代码中调用这个宏和除以 256 是一样的吗?

【问题讨论】:

    标签: c exit system-calls


    【解决方案1】:

    据我通过检查 Single Unix Spec 得知,您的 系统恰好将退出状态存储在倒数第二个八位字节中,但我不相信 the standard 会.因此,您至少应该出于以下几个原因使用宏:

    • 他们是正确的。对负数进行位移在不同的平台上会做不同的事情。它是否按照您想要的方式工作?我不知道。
    • 它们很简单。它立即清楚WEXITSTATUS 做了什么。其他方法则更少。如果你看到WIFSIGNALED的手卷版,你会认出来吗?比WIFSIGNALED 需要多长时间。
    • 它们是便携式的。按照规范的规定,它适用于每个系统(至少几乎每个类 Unix 系统)。

    【讨论】:

      【解决方案2】:

      如果状态变量是一个有符号的 16 位整数(一个 'short')在一台机器上,其中 'int' 是一个 32 位的数量,并且如果退出状态在 128..255 范围内,那么 WEXITSTATUS () 仍然给你一个正确的值,除以 256 或简单地向右移动会给你一个不正确的值。

      这是因为 short 将被符号扩展为 32 位,并且屏蔽会撤消符号扩展,在结果中留下正确的(正)值。

      如果机器使用 16 位整数,那么 WEXITSTATUS() 中的代码可能会先移位然后掩码以确保类似的行为:

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

      因为实现会为您处理这些细节,您应该使用 WEXITSTATUS() 宏。

      【讨论】:

        【解决方案3】:

        这个话题的真正问题是, 调用这个宏是一样的 在我的代码中除以 256?

        它可能总是在子进程正常终止的情况下工作(即,通过调用 exit(),而不是通过分段错误、断言失败等)。

        waitpid() 存储的状态编码了子进程被终止的原因和退出代码。原因存储在最低有效字节中(由status & 0xff 获得),退出代码存储在下一个字节中(由status & 0xff00 屏蔽并由WEXITSTATUS() 提取)。当进程正常终止时,原因为0,因此WEXITSTATUS 仅相当于移位8(或除以256)。但是,如果进程被信号(如SIGSEGV)杀死,则没有退出代码,您必须使用WTERMSIG从原因字节中提取信号号。

        【讨论】:

          【解决方案4】:

          这里的 0xff00 是一个二进制掩码 (link text)。将它与一个值相与会将所有位设置为零,除了第二个字节(从右数)。

          您应该只在已知正常退出的进程上使用WEXITSTATUS。此信息由WIFEXITED 宏提供。

          这个主题的真正问题是,在我的代码中调用这个宏和除以 256 是一样的吗?

          该宏使代码更具可读性,并保证可用于任何符合 Posix 的实现。据我所知,Posix 没有指定状态的格式,所以你不能指望你的代码在任何地方都能工作。

          【讨论】:

            猜你喜欢
            • 2021-05-10
            • 1970-01-01
            • 2012-07-16
            • 2013-11-05
            • 2012-01-26
            • 1970-01-01
            • 2012-05-08
            • 1970-01-01
            • 2015-10-23
            相关资源
            最近更新 更多