【赤石C++】BUILD_BUG_ON 宏
BUILD_BUG_ON
考虑一个问题:在没有 static_assert 的年代,如何确保在编译期抛出错误?
我们知道,在 C 语言中,无法创建负长度数组且数组长度会在编译期求值
1 | |
所以,利用这个特性就可以实现一个简易的 static_assert,当条件不满足时创建一个负数长度数组保证在编译期抛出错误
1 | |

但引入了几个新的问题:命名空间污染和运行时开销
C 语言不支持匿名数组,声明数组时必须指定变量名(声明必须绑定到标识符),会造成命名空间污染
1 | |
此外,在编译器优化能力不足时,多余的数组还可能导致多占用栈空间造成额外的运行时开销
解决方法是使用 sizeof 包裹,我们知道,sizeof 后面可以跟一个类型名(更准确的说法是“类型抽象声明符”),所以 sizeof(char[1]) 是合法语句,因为这里的 char[1] 并不是在创建数组,而是在描述一个类型,sizeof 只关心这个类型的大小,不需要创建实际对象
1 | |
不会造成命名空间污染,不会造成运行时开销(sizeof 也是编译期求值),Linux 内核的 BUILD_BUG_ON 就是这样实现的
1 | |

首先,!!(condition) 把任意表达式强制转为 0 或 1(布尔化)
当表达式为 1 时,宏被展开为 sizeof(char[-1]),否则被展开为 sizeof(char[1])
1 | |
【赤石C++】BUILD_BUG_ON 宏
https://crackme.net/articles/bulid_bug_on/