【赤石C++】BUILD_BUG_ON宏

admin 2026-02-09 00:55:02 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了Linux内核中BUILD_BUG_ON宏的实现原理。利用C语言无法创建负长度数组且数组长度编译期求值的特性,通过sizeof(char[1-2*!!(condition)])实现编译期断言。!!(condition)将条件布尔化为0或1,条件为真时产生负长度数组触发编译错误。相比早期使用命名数组的实现,sizeof方案避免了命名空间污染和运行时开销,是static_assert出现前的经典编译期检查技术。 综合评分: 78 文章分类: 安全开发,代码审计,二进制安全


cover_image

【赤石C++】BUILD_BUG_ON 宏

原创

crackme.net crackme.net

crackme安全实验室

2026年2月8日 18:36 河南

BUILD_BUG_ON

考虑一个问题:在没有 static_assert 的年代,如何确保在编译期抛出错误?

我们知道,在 C 语言中,无法创建负长度数组且数组长度会在编译期求值

// 无法创建负长度数组
char a[-1];

// 数组长度编译期求值
char a[2 * 3]; // sizeof(a) == 6

所以,利用这个特性就可以实现一个简易的 static_assert,当条件不满足时创建一个负数长度数组保证在编译期抛出错误

#define my_static_assert(condition) char a[condition ? 1 : -1]

但引入了几个新的问题:命名空间污染和运行时开销

C 语言不支持匿名数组,声明数组时必须指定变量名(声明必须绑定到标识符),会造成命名空间污染

// 不支持匿名数组,这是非法语句
char[1];

此外,在编译器优化能力不足时,多余的数组还可能导致多占用栈空间造成额外的运行时开销

解决方法是使用 sizeof 包裹,我们知道,sizeof 后面可以跟一个类型名(更准确的说法是“类型抽象声明符”),所以 sizeof(char[1]) 是合法语句,因为这里的 char[1] 并不是在创建数组,而是在描述一个类型,sizeof 只关心这个类型的大小,不需要创建实际对象

// 合法语句
sizeof(char[1]);

不会造成命名空间污染,不会造成运行时开销(sizeof 也是编译期求值),Linux 内核的 BUILD_BUG_ON 就是这样实现的

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

首先,!!(condition) 把任意表达式强制转为 0 或 1(布尔化)

当表达式为 1 时,宏被展开为 sizeof(char[-1]),否则被展开为 sizeof(char[1])

// 正常编译
sizeof(char[1]);

// 抛出错误
sizeof(char[-1]);

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:crackme安全实验室 crackme.net crackme.net《【赤石C++】BUILDBUGON 宏》

FOTA信息安全 网络安全文章

FOTA信息安全

文章总结: 本文综述了FOTA信息安全领域的学术研究进展,系统介绍了四大技术方向:TUF和Uptane安全更新框架、基于CP-ABE属性加密的STRIDE技术、
一致性Hash算法详解 网络安全文章

一致性Hash算法详解

文章总结: 本文详解一致性Hash算法在分布式系统中的应用原理。针对普通Hash算法在节点变动时需全量迁移数据的问题,一致性Hash通过环形空间映射和顺时针定位
评论:0   参与:  0