【C语言笔记】【宏定义系列】 编译时检查是否2的幂

文章介绍了Linux内核中用于编译时检查常量是否为2的幂次方的宏定义`BUILD_BUG_ON_NOT_POWER_OF_2`。当表达式不是2的幂时,编译将失败。这个宏通过`BUILD_BUG_ON`和其他位运算来实现检查,确保常量是2的幂次方。
摘要由CSDN通过智能技术生成

【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
错误: 无名数组的大小为负

实现过程

  1. BUILD_BUG_ON

    BUILD_BUG_ON_NOT_POWER_OF_2中使用了另外一个宏BUILD_BUG_ON,用于在编译时检查传入的条件是否为真,如果条件为真则会编译失败,如果条件为假,则编译正常。

    详见BUILD_BUG_ON

  2. (n) == 0

    如果常量表达式n的结果为 0,说明不是 2 的幂次方。

  3. (((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。

  4. (n) == 0 || (((n) & ((n) - 1)) != 0)

    上面的 2,3两点进行或运算,得出最后的条件变量,如果为 2 的幂次方则条件为假,反之为真。

  5. 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值