Linux内核BUILD_BUG_ON_INVALID宏疑似无作用?求技术答疑
关于Linux内核BUILD_BUG_ON_INVALID宏的疑问与解答
原内核宏定义
#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
测试代码与编译方式
用户的测试代码(去掉了内核的__force属性):
#include <stdio.h> #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof(( long)(e)))) #define true 1 int main() { BUILD_BUG_ON_INVALID(true); return 0; }
编译命令:gcc -Wall -Wextra -c test.c(使用GCC 11.4.0版本)
核心疑问
测试时将true设为0或1都无警告输出,想明确:什么样的表达式才属于该宏针对的“无效表达式”?
解答
这个宏的核心逻辑是利用编译期类型转换的合法性检查触发构建错误(而非警告),它针对的“无效表达式”是指无法被强制转换为long类型的表达式,而非逻辑上的真假值。以下是关键细节:
__force的作用:内核宏中的__force是GCC扩展属性,用来跳过常规的类型转换安全检查,但如果表达式本身根本不具备转换为long的可能性,编译器依然会在计算sizeof时报错——这就是宏要触发的编译期错误。会触发错误的无效表达式示例:
- 不兼容类型的指针:比如将函数指针
void (*func)(int)强制转换为long,在部分架构下函数指针与数据指针长度不同,或类型转换不被允许,直接编译失败。 - 非标量类型:直接传入结构体变量,比如
struct foo s; BUILD_BUG_ON_INVALID(s);,结构体无法直接转换为long,触发编译错误。 - 位域成员:结构体中的位域,比如
struct { unsigned int a:3; } s; BUILD_BUG_ON_INVALID(s.a);,位域不能被强制转换为普通整数类型,即使带__force也会报错。
- 不兼容类型的指针:比如将函数指针
测试无反应的原因:你测试用的
0或1都是普通整数,与long类型兼容,无论是否带__force,类型转换都完全合法,编译器不会产生任何警告或错误。此外你去掉了内核宏中的__force,但普通整数转换本就没有安全问题,因此不会触发任何反馈。
内容的提问来源于stack exchange,提问作者pluto
相关产品推荐
相关产品推荐

