【C语言笔记】【宏定义系列】 编译时检查是否为2的幂
linux宏定义系列内容。用于记录在linux kernel之中各式各样的宏定义☺。
宏定义说明
用于在编译时检查常量表达式是不是2的 n 次幂,如果常量表达式不是2的 n 次幂,则强制编译错误,编译器报错,反之如果常量表达式是2的 n 次幂,则编译正常。
该宏定义来自linux kernel 3.10。
实现代码
/* Force a compilation error if a constant expression is not a power of 2 */
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) \
BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
宏定义中:
n
表示要用于判断的常量表达式。
BUILD_BUG_ON
用于在编译时检查一个条件是否为真,如果条件为真则会编译失败,详见BUILD_BUG_ON。
示例程序
当常量表达式为 2 的幂次方时,可以正常编译通过。
int main(int argc, char* argv[])
{
BUILD_BUG_ON_NOT_POWER_OF_2(64);
BUILD_BUG_ON_NOT_POWER_OF_2(128);
BUILD_BUG_ON_NOT_POWER_OF_2(256);
BUILD_BUG_ON_NOT_POWER_OF_2(512);
BUILD_BUG_ON_NOT_POWER_OF_2(1024);
return 0;
}
当将常量表达式修改为不是 2 的幂次方时:
int main(int argc, char* argv[])
{
BUILD_BUG_ON_NOT_POWER_OF_2(0);
BUILD_BUG_ON_NOT_POWER_OF_2(1000);
return 0;
}
则编译失败,提示
error: size of unnamed array is negative
错误: 无名数组的大小为负
实现过程
-
BUILD_BUG_ON
BUILD_BUG_ON_NOT_POWER_OF_2
中使用了另外一个宏BUILD_BUG_ON
,用于在编译时检查传入的条件是否为真,如果条件为真则会编译失败,如果条件为假,则编译正常。详见BUILD_BUG_ON。
-
(n) == 0
如果常量表达式
n
的结果为 0,说明不是 2 的幂次方。 -
(((n) & ((n) - 1)) != 0)
这是一个常用的用于判断一个数是否是 2 的幂次方的表达式,n 的值需要大于0。如果 n 是 2 的幂次方,n 减 1 之后二进制的低位全部变为 1,然后与 n 相与之后,结果就会为 0。例如一个 2 的 4 次幂数值 16,二进制值0b10000,减一后变为 15,二进制值0b1111,与操作后变为0:
0001 0000 & 0000 1111 ------------- 0000 0000
所以如果常量表达式
n
是 2 的幂次方,则等于0,不是 2 的幂次方则不等于0。 -
(n) == 0 || (((n) & ((n) - 1)) != 0)
上面的 2,3两点进行或运算,得出最后的条件变量,如果为 2 的幂次方则条件为假,反之为真。
-
BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
最后传入
BUILD_BUG_ON
宏中,实现常量表达式不是 2 的幂次方,则强制编译错误,编译器报错,反之如果常量表达式是 2 的幂次方,则编译通过。
[参考资料]
linux kernel 3.10
/include/linux/bug.h
本文链接:https://blog.csdn.net/u012028275/article/details/129855104