什么是“: – !!”用C代码?

原创 287865  2019-07-10 23:21 

我在 /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 。 ( 偶尔会讨论这是一个令人困惑的名字 。)

你应该读这样的表达:

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

  2. [

    !!(e) :逻辑上否定两次: 0 如果 e == 0 ;否则 1

  3. -!!(e) :在数字上否定第2步的表达: 0 如果是 0 ;否则 -1

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

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

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


有些人问过:为什么不只是使用 assert

keithmo的回答在这里有一个很好的回应:

这些宏实现了编译时测试,而assert()是一个运行时测试。

完全正确。您不希望在运行时检测到内核中可能早先发现的问题!它是操作系统的关键部分。无论在何种程度上,在编制时都可以发现问题,那就更好了。

本文地址:https://www.hedasudi.com/2827.shtml
版权声明:本文为原创文章,版权归 287865 所有,欢迎分享本文,转载请保留出处!