首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >C 中的这串符号是什么意思

C 中的这串符号是什么意思

作者头像
ClearSeve
发布2022-02-10 19:03:07
发布2022-02-10 19:03:07
2.3K0
举报
文章被收录于专栏:ClearSeveClearSeve

问题

我在 /usr/include/linux/kernel.h 里遇到了一个奇怪的宏,

代码语言:javascript
复制
/* 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 的。如果不为 0,编译器就会报错。(其实就是我们常说的静态断言)

这个宏的名字其实起的不好,应该为BUILD_BUG_OR_ZERO,这里有个相关的讨论:occasional discussions about whether this is a confusing name

下面来分析下上面的宏:

代码语言:javascript
复制
sizeof(struct { int: -!!(e); }))
  1. (e):计算 e 表达式
  2. !!(e):两次逻辑否操作。也就是,如果 e == 0,就返回 0,否则返回 1
  3. -!!(e):对上面的第 2 步得到的值置负。也就是,0 的负数还是 0,1 的负数为 -1
  4. struct{int: -!!(0);} --> struct{int: 0;}:根据第 3 步,如果是 0,那么就声明一个结构体,里边定义了一个位域长度为 0 的匿名位域变量,此时编译正常通过
  5. struct{int: -!!(1);} --> struct{int: -1;}:但如果是 -1 的话,位域长度为负数,那编译器就会报错了

为什么不用assert呢?

因为assert是运行期判断,上面的宏是编译期。不过自 C++ 11 起,也支持静态断言了,可以参考 static_assert

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 回答
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档