什么是“:-!!"在 C 代码中? [英] What is ":-!!" in C code?
问题描述
我在中遇到了这个奇怪的宏代码/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); }))
:-!!
有什么作用?
推荐答案
这实际上是一种检查表达式 e 是否可以计算为 0 的方法,如果不是,则构建失败.
这个宏有点名不副实;它应该更像 BUILD_BUG_OR_ZERO
,而不是 ...ON_ZERO
.(已经偶尔讨论这是否是一个令人困惑的名称.)
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)
:计算表达式e
.
!!(e)
:逻辑取反两次:0
if e == 0
;否则 1
.
!!(e)
: Logically negate twice: 0
if e == 0
; otherwise 1
.
-!!(e)
:对第 2 步中的表达式进行数值求反:0
如果它是 0
;否则 -1
.
-!!(e)
: Numerically negate the expression from step 2: 0
if it was 0
; otherwise -1
.
struct{int: -!!(0);} -->struct{int: 0;}
:如果它是零,那么我们声明一个结构体,它带有一个宽度为零的匿名整数位域.一切都很好,我们照常进行.
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;}
:另一方面,如果它不为零,那么它将是一些负数.声明任何具有负宽度的位域都是编译错误.
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.
所以我们要么在结构中使用宽度为 0 的位域,这很好,要么使用负宽度的位域,这是编译错误.然后我们取sizeof
那个字段,所以我们得到一个具有适当宽度的size_t
(在e
为零的情况下为零).
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 a size_t
with the appropriate width (which will be zero in the case where e
is zero).
有人问:为什么不直接使用assert
?
Some people have asked: Why not just use an assert
?
keithmo 的回答这里有很好的反响:
这些宏实现了编译时测试,而 assert() 是运行时测试.
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.
这篇关于什么是“:-!!"在 C 代码中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!