c - 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。 (已经有 occasional discussions about whether this is a confusing name 。)

您应该像这样阅读表达式:

sizeof(struct { int: -!!(e); }))
  1. (e):计算表达式e.

  2. !!(e):逻辑否定两次:0 if e == 0;否则 1.

  3. -!!(e):数值否定步骤 2 中的表达式:0 if it is 0;否则 -1.

  4. struct{int: -!!(0);} --> struct{int: 0;}: 如果为零,那么我们声明一个带有匿名整数的结构体宽度为零的位域。一切都很好,我们照常进行。

  5. struct{int: -!!(1);} --> struct{int: -1;}:另一方面,如果它不是 零,那么它将是一些负数。用 negative 宽度声明任何位域都是编译错误。

所以我们要么在结构中得到一个宽度为 0 的位域,这很好,要么是一个具有负宽度的位域,这是一个编译错误。然后我们取 sizeof 那个字段,所以我们得到一个具有适当宽度的 size_t (在 e 为零的情况下将为零) .


有人问:为什么不直接使用assert

keithmo's answer这里有一个很好的回应:

These macros implement a compile-time test, while assert() is a run-time test.

完全正确。您不想在运行时检测到您的内核 中可能更早发现的问题!它是操作系统的关键部分。在编译时可以检测到任何程度的问题,那就更好了。

关于c - C 代码中的 ":-!!"是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9229601/

相关文章:

python - 如何在 Python 中找到当前的操作系统?

python - Django Model() 与 Model.objects.create()

linux - 如何在 Linux 中更改 echo 的输出颜色

python - 捕获异常时,如何获取类型、文件和行号?

python - 如果键存在,则删除字典项

linux - 如何在 Linux shell 脚本中提示是/否/取消输入?

linux - 如何根据通配符匹配递归查找当前文件夹和子文件夹中的所有文件?

linux - 如何删除导出的环境变量?

bash - 如何使用 Bash 将标准输出和标准错误重定向并 append 到文件中

linux - 如何递归 grep 所有目录和子目录?