在kernel.h的min宏中,“(void)(& _min1 ==& _min2)”的功能是什么?

时间:2011-04-08 13:16:52

标签: c linux-kernel

kernel.h min中定义为:

#define min(x, y) ({                \
    typeof(x) _min1 = (x);          \
    typeof(y) _min2 = (y);          \
    (void) (&_min1 == &_min2);      \
    _min1 < _min2 ? _min1 : _min2; })

我不明白行(void) (&_min1 == &_min2);的作用。是某种类型检查还是什么?

6 个答案:

答案 0 :(得分:58)

声明

(void) (&_min1 == &_min2);

是有保证的“无操作”。所以唯一的原因是它的副作用。

但声明没有副作用!

但是:它强制编译器在xy的类型不兼容时发出诊断
请注意,使用_min1 == _min2进行测试会隐式地将其中一个值转换为另一个值。

所以,我猜,这就是它的作用。 它在编译时验证xy的类型是否兼容

答案 1 :(得分:18)

include/linux/kernel.h中的代码将此称为“不必要的”指针比较。 这实际上是一种严格的类型检查,确保xy的类型相同。

此处类型不匹配将导致编译错误或警告。

答案 2 :(得分:11)

这提供了类型检查,指针之间的相等性应该在兼容类型之间,gcc将为不是这样的情况提供警告。

我们可以看到指针之间的相等性要求指针来自draft C99 standard部分6.5.9 Equality运算符中的兼容类型,其中说:

  

以下其中一项应成立:

并包括:

  

两个操作数都是指向兼容类型的限定或非限定版本的指针;

我们可以从6.2.7 兼容类型和复合类型中找到兼容类型的内容,其中包含:

  

如果类型相同,则两种类型具有兼容类型

关于osnews的讨论也涵盖了这一点,它的灵感来自具有相同代码示例的GCC hacks in the Linux kernel文章。答案是:

  

与类型检查有关。

     

制作一个简单的程序:

int x = 10; 
long y = 20;
long r = min(x, y);
     

给出以下警告:警告:不同指针的比较   类型缺乏演员

答案 3 :(得分:6)

请参阅http://www.osnews.com/comments/20566解释:

  

它与类型检查有关。

     

制作一个简单的程序:

int x = 10; 
long y = 20; 
long r = min(x, y); 
     

发出以下警告:   警告:不同指针类型的比较缺少强制转换

答案 4 :(得分:4)

找到答案here

&#34;它与类型检查有关。 制作一个简单的程序:

int x = 10; 
long y = 20; 
long r = min(x, y); 

发出以下警告: 警告:不同指针类型的比较缺少强制转换&#34;

答案 5 :(得分:0)

Linux内核充满了这样的东西(为了“类型安全”和其他类似的考虑因素而无端gcc特定的黑客攻击),我认为这是非常糟糕的做法,并敦促你不要遵循它,除非有人要求你到。

pmg对于黑客的目的是正确的,但任何理智的人都会将min定义为((x)<(y)?(x):(y))

请注意,内核定义排除了许多正确的用法,例如:其中一个参数为int,另一个参数为long。我怀疑他们真正想要排除的是签名不匹配,例如min(-1,1U)是1.更好的断言方法是对((1?-1:(x))<0)==((1?-1:(y))<0)使用编译时断言。请注意,这不需要任何特定于gcc的黑客。