什么是“:-!!"在 C 代码中? [英] What is ":-!!" in C code?

查看:118
本文介绍了什么是“:-!!"在 C 代码中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在中遇到了这个奇怪的宏代码/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); }))

  1. (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆