“(void) (&_min1 == &_min2)”的作用是什么?在 kernel.h 的 min 宏中?
在 kernel.h 中,分钟是定义为:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
我不明白行 (void) (&_min1 == &_min2);
的作用。是某种类型检查还是什么?
In kernel.h min is defined as:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
I don't understand what the line (void) (&_min1 == &_min2);
does. Is it some kind of type checking or something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
请参阅 http://www.osnews.com/comments/20566 其中解释:
See http://www.osnews.com/comments/20566 which explains:
找到答案这里
“它与类型检查有关。
制作一个简单的程序:
给出以下警告:
警告:不同指针类型的比较缺少强制转换”
Found answer here
"It has to do with typechecking.
Making a simple program:
Gives the following warning:
warning: comparison of distinct pointer types lacks a cast"
Linux 内核充满了这样的东西(出于“类型安全”和其他类似考虑而进行的针对 gcc 的无偿黑客攻击),我认为这是非常糟糕的做法,并敦促您不要遵循它,除非有人要求您这样做。
pmg 关于黑客攻击的目的是正确的,但任何理智的人都会将
min
定义为((x)<(y)?(x):(y))
。请注意,内核定义排除了许多正确的用法,例如,一个参数是
int
,另一个参数是long
。我怀疑他们真正想要排除的是符号不匹配,例如min(-1,1U)
是 1。断言这一点的更好方法是使用的编译时断言>((1?-1:(x))<0)==((1?-1:(y))<0)
。请注意,这不需要任何特定于 gcc 的 hack。The Linux kernel is full of stuff like this (gratuitous gcc-specific hacks for the sake of "type safety" and other similar considerations), and I would consider it very bad practice and urge you not to follow it unless someone requires you to.
pmg is right about the purpose of the hack, but any sane person would define
min
as((x)<(y)?(x):(y))
.Note that the kernel definition precludes many correct usages, e.g. where one argument is
int
and another islong
. I suspect what they really wanted to preclude is signedness mismatches, where for examplemin(-1,1U)
is 1. A better way to assert this would be to use a compile-time assertion for((1?-1:(x))<0)==((1?-1:(y))<0)
. Note that this does not require any gcc-specific hacks.该声明
是保证“无操作”的。所以它存在的唯一原因是它的副作用。
但该声明没有任何副作用!
但是:当
x
和y
的类型不兼容时,它会强制编译器发出诊断。请注意,使用
_min1 == _min2
进行测试会隐式地将其中一个值转换为另一种类型。所以,这就是它的作用。 它在编译时验证
x
和y
的类型是否兼容。The statement
is a guaranteed "no-op". So the only reason it's there is for its side effects.
But the statement has no side effects!
However: it forces the compiler to issue a diagnostic when the types of
x
andy
are not compatible.Note that testing with
_min1 == _min2
would implicitly convert one of the values to the other type.So, that is what it does. It validates, at compile time, that the types of
x
andy
are compatible.include/linux/kernel.h 中的代码引用这是一个“不必要的”指针比较。
这实际上是严格的类型检查,确保
x
和y
的类型相同。此处的类型不匹配将导致编译错误或警告。
The code in include/linux/kernel.h refers to this as an "unnecessary" pointer comparison.
This is in fact a strict type check, ensuring that the types of
x
andy
are the same.A type mismatch here will cause a compilation error or warning.
这提供了类型检查,指针之间的相等性应在兼容类型之间,并且 gcc 将为情况并非如此的情况提供警告。
我们可以从 C99 标准草案 部分
6.5.9
相等运算符 内容如下:并包括:
我们可以从
6.2.7
兼容类型和复合类型 中找到什么是兼容类型,其中说道:osnews 上的讨论也涵盖了这一点受到 Linux 内核中的 GCC hack 文章的启发它具有相同的代码示例。答案说:
This provides for type checking, equality between pointers shall be between compatible types and
gcc
will provide a warning for cases where this is not so.We can see that equality between pointers requires that the pointers be of compatible types from the draft C99 standard section
6.5.9
Equality operators which says:and includes:
and we can find what a compatible type is from section
6.2.7
Compatible type and composite type which says:This discussion on osnews also covers this and it was inspired by the GCC hacks in the Linux kernel article which has the same code sample. The answer says: