C “的功能是什么?”;(无效)(“最小1=”最小2“);在kernel.h中的min宏中?
在最小值中,定义为:C “的功能是什么?”;(无效)(“最小1=”最小2“);在kernel.h中的min宏中?,c,linux-kernel,C,Linux Kernel,在最小值中,定义为: #define min(x, y) ({ \ typeof(x) _min1 = (x); \ typeof(y) _min2 = (y); \ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) 定义最小值(x,y)({\ 类型(x)_min1=(x)\ 类型(y)_m
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
定义最小值(x,y)({\
类型(x)_min1=(x)\
类型(y)_min2=(y)\
(无效)(和(1)==(和(2));\
_min1<\u min2?\u min1:\u min2;})
我不明白这行代码是什么(void)(&u min1==&u min2)代码>可以。这是某种类型的类型检查还是什么
(void) (&_min1 == &_min2);
是保证的“无操作”。所以它存在的唯一原因是它的副作用
但是这个声明没有副作用
但是:当x
和y
的类型不兼容时,它会强制编译器发出诊断。请注意,使用
\u min1==\u min2
进行测试将隐式地将一个值转换为另一个类型
所以,它就是这样做的它在编译时验证x
和y
的类型是否兼容请参见以下说明:
这与打字有关
制作一个简单的程序:
int x = 10;
long y = 20;
long r = min(x, y);
int x = 10;
long y = 20;
long r = min(x, y);
给出以下警告:
警告:不同指针类型的比较缺少强制转换
<> P> Linux内核中充满了这样的东西(出于“类型安全”和其他类似的考虑),GCC专用的黑客攻击,我会认为这是非常糟糕的做法,并敦促你不要跟随它,除非有人要求你这样做。 pmg关于黑客攻击的目的是正确的,但任何理智的人都会将
min
定义为((x)中的代码将其称为“不必要的”指针比较。
这实际上是一种严格的类型检查,确保x
和y
的类型相同
此处的类型不匹配将导致编译错误或警告。这提供了类型检查,指针之间的相等性应在兼容类型之间,并且gcc
将为不匹配的情况提供警告
我们可以看到,指针之间的相等要求指针为6.5.9
相等运算符一节中的兼容类型,该节说明:
下列情况之一应适用:
包括:
两个操作数都是指向兼容类型的合格或不合格版本的指针
我们可以从第6.2.7节兼容类型和复合类型中找到什么是兼容类型,其中说明:
如果两种类型的类型相同,则它们具有兼容的类型
关于的讨论也涵盖了这一点,它受到了具有相同代码示例的文章的启发。答案是:
和打字有关
制作一个简单的程序:
int x = 10;
long y = 20;
long r = min(x, y);
给出以下警告:警告:不同指针的比较
类型缺少类型
找到答案
“这与打字有关。
制作一个简单的程序:
int x = 10;
long y = 20;
long r = min(x, y);
int x = 10;
long y = 20;
long r = min(x, y);
给出以下警告:
警告:不同指针类型的比较缺少强制转换”奇怪。在我看来,地址比较会迫使实际计算和存储_min1和_min2,从而计算和存储x和y,但在下一行将_min1与_min2进行比较时,这不应该发生吗?仅供参考,这个问题与这个问题合并了,因此您现在有了一些新的答案。也许最好说它已经发生了没有运行时的副作用,而是编译时的副作用。出于某种原因,这听起来不太对。如果类型不兼容,那么宏无论如何都不会工作。也就是说,如果你给宏传递一个struct foo和一个int,你无论如何都会得到编译时错误,即使没有那一行。@Robert:例如,试试看,m=min(42,43.0)
。有或没有所讨论的语句。@pmg:所以这一点不是不兼容的类型,而是它们希望确保两个参数的类型完全相同?int
和volatile const int
是不同的,但兼容的类型!但是((x)每个人都知道你不会将带有副作用的表达式传递给min/max宏。这是你学习C的第一件事。将GCC指定为唯一受支持的编译器是前进的障碍。当然,但我从另一个方面了解到了这一点:你不会像那样将min/max作为宏来编写。内核需要其他各种东西(asm
blocks,linker-section-annotations)无论如何都不是标准C的一部分,所以指定GNU C并不是一个真正的损失。@Aktau:不,这个“把戏”它很容易出错。?:
运算符的结果有一种类型,其规则取决于第二个和第三个操作数的类型。如果x
或y
中的一个具有大于int
的无符号秩类型,但另一个没有,则等式将为false;一个等式将为大的正vvalue和另一个值将是-1。正是在这种情况下,min
和max
宏可能会以意外且可能危险的方式运行。但是如果它们不相同,会发生什么?看起来代码无论如何都会运行。这不是在平等性检查上浪费cpu时间吗?不,这是一个nop。它在void contex中调用t所以结果无关紧要,优化器会完全消除它。@user10607:是的。它没有任何副作用,并且它的结果被丢弃,没有理由保留它。@user10607:否。它被编译(发生类型检查的魔力),然后被优化器丢弃(仍在编译阶段).合并自合并自