什么是" - !!"在C code吗? [英] What is ":-!!" in C code?
问题描述
我碰上了这个陌生的宏code在<一个href=\"https://github.com/torvalds/linux/blob/ff2d8b19a3a62559afba1c53360c8577a7697714/include/linux/kernel.h#L677-L682\">/usr/include/linux/kernel.h:
/ *强制编译错误,如果条件为真,还会产生
结果(值0和size_t类型),因此,可以使用前pression
例如在结构初始化(或在前所未有其他逗号前pressions
不允许)。 * /
#定义BUILD_BUG_ON_ZERO(E)(的sizeof(结构{INT: - !!(E);}))
#定义BUILD_BUG_ON_NULL(E)((无效*)的sizeof(结构{INT: - !!(E);}))
这是什么: - ?!!
做
这是,实际上,办法来检查前pressionË是否可以评价为0,如果没有,构建失败
宏是有些名不副实;它应该像 BUILD_BUG_OR_ZERO
,而不是 ... ON_ZERO
更多的东西。 (已经有 关于这是否是一个令人困惑的名字 偶尔讨论STRONG>)
您应该阅读前pression是这样的:
的sizeof(结构{INT: - !!(E);}))
-
(E)
:计算前pression电子
-
!!(E)
:从逻辑上否定了两次:0
如果Ë== 0
;否则1
。 -
- !!(E)
:数控否定:0
如果Ë== 0
;否则1
。 -
结构{INT: - !!(0);} - &GT;结构{INT:0;}
:如果是零,那么我们宣布与具有宽度为零匿名整数位域的结构体。一切都很好,我们继续正常。 -
结构{INT: - !!(1);} - &GT;结构{INT:-1;}
:在另一方面,如果它的不是的零,那么这将是一些负数。声明任何位域的负的宽度为编译错误。
所以我们会以风与具有在结构宽度0位域,这是很好的,或负宽度,这是一个编译错误位域。然后我们采取的sizeof
的领域,使我们得到了一个为size_t
与适当的宽度(这将是零的情况下其中,电子
为零)。
有些人问:为什么不直接使用断言
keithmo的回答具有良好的响应:
这些宏实现编译时的测试,而断言()是一个运行时测试。
块引用>分毫不差。你不想来检测可能已经陷入早些时候在运行时在你的内核问题的!它的操作系统的关键部分。到任何可以在编译时被检测到的程度问题,那就更好了。
I bumped into this strange macro code in /usr/include/linux/kernel.h:
/* Force a compilation error if condition is true, but also produce a result (of value 0 and type size_t), so the expression can be used e.g. in a structure initializer (or where-ever else comma expressions aren't permitted). */ #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
What does
:-!!
do?解决方案This is, in effect, a way to check whether the expression e can be evaluated to be 0, and if not, to fail the build.
The macro is somewhat misnamed; it should be something more like
BUILD_BUG_OR_ZERO
, rather than...ON_ZERO
. (There have been occasional discussions about whether this is a confusing name.)You should read the expression like this:
sizeof(struct { int: -!!(e); }))
(e)
: Compute expressione
.
!!(e)
: Logically negate twice:0
ife == 0
; otherwise1
.
-!!(e)
: Numerically negate:0
ife == 0
; otherwise-1
.
struct{int: -!!(0);} --> struct{int: 0;}
: If it was zero, then we declare a struct with an anonymous integer bitfield that has width zero. Everything is fine and we proceed as normal.
struct{int: -!!(1);} --> struct{int: -1;}
: On the other hand, if it isn't zero, then it will be some negative number. Declaring any bitfield with negative width is a compilation error.So we'll either wind up with a bitfield that has width 0 in a struct, which is fine, or a bitfield with negative width, which is a compilation error. Then we take
sizeof
that field, so we get asize_t
with the appropriate width (which will be zero in the case wheree
is zero).
Some people have asked: Why not just use an
assert
?keithmo's answer here has a good response:
These macros implement a compile-time test, while assert() is a run-time test.
Exactly right. You don't want to detect problems in your kernel at runtime that could have been caught earlier! It's a critical piece of the operating system. To whatever extent problems can be detected at compile time, so much the better.
这篇关于什么是&QUOT; - !!&QUOT;在C code吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!