62

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);。是某种类型检查还是什么?

4

6 回答 6

63

该声明

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

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

但是声明没有副作用!

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

所以,这就是它的作用。它在编译时验证x和的类型y是否兼容

于 2011-04-08T13:24:28.673 回答
19

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

这里的类型不匹配会导致编译错误或警告。

于 2014-11-03T15:49:22.993 回答
11

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

我们可以看到,指针之间的相等性要求指针是草案 C99 标准部分平等运算符中的兼容类型,该部分说:6.5.9

应满足下列条件之一:

包括:

两个操作数都是指向兼容类型的合格或不合格版本的指针;

我们可以从Compatible type 和 composite type部分找到兼容类型是什么,它说:6.2.7

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

这个关于osnews的讨论也涵盖了这一点,它受到Linux 内核文章中的 GCC hacks 的启发,该文章具有相同的代码示例。答案说:

与类型检查有关。

制作一个简单的程序:

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

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

于 2014-11-03T15:49:33.810 回答
6

请参阅http://www.osnews.com/comments/20566,其中解释了:

它与类型检查有关。

制作一个简单的程序:

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

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

于 2011-04-08T13:30:32.357 回答
4

在这里找到答案

“它与类型检查有关。制作一个简单的程序:

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

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

于 2014-11-03T15:50:10.083 回答
0

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

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

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

于 2011-04-08T13:46:52.807 回答