Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C “的功能是什么?”;(无效)(“最小1=”最小2“);在kernel.h中的min宏中?_C_Linux Kernel - Fatal编程技术网

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:否。它被编译(发生类型检查的魔力),然后被优化器丢弃(仍在编译阶段).合并自合并自