【问题标题】:GCC typeof extension and math on typeof resultGCC typeof 扩展和 typeof 结果的数学运算
【发布时间】:2019-10-19 12:07:45
【问题描述】:

今天我在 Linux 内核中遇到了这个宏 (include/linux/kernel.h)

#define DIV_ROUND_CLOSEST(x, divisor)(          \
{                           \
    typeof(x) __x = x;              \
    typeof(divisor) __d = divisor;          \
    (((typeof(x))-1) > 0 ||  /* <-- why does this work */   \
     ((typeof(divisor))-1) > 0 || (__x) > 0) ?  \
        (((__x) + ((__d) / 2)) / (__d)) :   \
        (((__x) - ((__d) / 2)) / (__d));    \
}                           \
)

现在,我了解了宏的用途,并且它以某种方式利用了“语句表达式”(下面的链接提到了这一点)。我不明白((typeof(x))-1) &gt; 0 有什么用处。从 gcc 文档中的 this link 开始,我想我了解了如何使用 typeof 扩展名。但是知道这一点似乎并不能回答它在这个宏中是如何使用的。根据我自己的实验,(typeof(x)-1) 似乎除了-1 之外没有任何评估结果,所以这总是小于 0(即 false对于三元的前两部分)?


如果已经回答了,请指点我。我进行了搜索,但我的尝试没有返回特定于此用法的结果。

【问题讨论】:

  • 我怀疑它正在测试类型是否是无符号的。如果typeof(x) 是某个无符号整数类型,那么(((typeof(x))-1) 是正数。

标签: c gcc linux-kernel typeof


【解决方案1】:

它没有使用(typeof(x)-1) - 它使用((typeof(x))-1),其形式为(type)value - 即,它是一个强制转换表达式。

它将值-1 转换为与表达式x 相同的类型,然后测试结果是否大于零。如果x 具有有符号整数类型或浮点类型,则结果将为假,如果x 具有无符号整数类型,则结果将为真,而对于大多数其他类型,行为将是未定义的。

【讨论】:

  • 对于大多数其他类型,强制转换将违反约束(需要诊断)。我想不出任何没有诊断的情况下这将是未定义的行为
  • @M.M:我相信指针类型(它将使用&gt;比较不在同一个对象中的两个指针)。在这里讨论标准的细节有点愚蠢,因为整个结构是一个扩展。
  • 谢谢!我必须说,它是如此明显,我应该看到它。这完全解释了为什么在我进行测试时,我必须将它包装在额外的括号中。我只是没有意识到这是一个演员表。我一直在尝试“减去 1”,但这是行不通的。现在,我知道为什么了。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2013-01-18
  • 2011-02-08
  • 2023-03-09
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多