前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C/C++黑魔法-编译期断言

C/C++黑魔法-编译期断言

作者头像
Qt君
发布2019-07-15 17:46:19
6710
发布2019-07-15 17:46:19
举报
文章被收录于专栏:跟Qt君学编程

今天查看Linux内核源码,出现一个很奇怪的用法。可以在静态编译期的断言。

1. 内核源码 kernel.h

  • BUILD_BUG_ON_ZERO判断表达式非零值编译器报错;
  • BUILD_BUG_ON_NULL判断表达式指针地址非空报错。
代码语言: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); }))

2. 源码解析

  • (e):计算表达式e;
  • !!(e):逻辑否定两次;
  • -!!(e):0如果是0; 否则-1;
  • struct{int:-!!(0);}-->struct{int:0;}:如果它为零,那么我们声明一个结构,其中包含一个宽度为零的匿名整数位域。这样会编译正常;
  • struct{int:-!!(1);}-->struct{int:-1;}:如果它不是零,那么它将是一些负数。声明任何具有负宽度的位域是编译错误。
  • 利用位域的宽度做编译判断,因为任何负数的位域都是错误的。

3. 为什么不使用断言?

  • 静态断言宏实现了编译时测试,断言宏assert是一个运行时测试;
  • 可以在编译器找出错误。无论在何种程度上,在编译时都可以检测到问题,就更好了。特别是在操作系统的关键部分。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 内核源码 kernel.h
  • 2. 源码解析
  • 3. 为什么不使用断言?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档