未加inline的static const变量用offsetof初始化为何报错?
问题原因解析
首先明确两个核心前提:
- 定义
struct A时,内部的B<A> b;会触发B<A>的模板实例化,但此时A尚未完成定义,属于不完整类型。 offsetof宏的硬性要求:第一个参数必须是完整类型,否则编译器会判定为非法使用并报错。
不加inline时报错的原因
对于模板类中的非inline static const成员,类内初始化属于常量声明,要求初始化表达式必须是合法的常量表达式。
当实例化B<A>时,编译器需要立即计算offsetof(A, b)这个表达式,但此时A是不完整类型,直接违反了offsetof对完整类型的要求,因此触发Offsetof of incomplete type 'A'(不完整类型'A'的offsetof使用)的错误。
添加inline后正常运行的原因
inline修饰的静态数据成员,其类内初始化属于定义,且初始化表达式的求值时机被延迟到该成员第一次被odr-used(比如取地址、直接使用其值等)的时候。
在你的代码中,shift成员从未被使用,所以初始化表达式offsetof(A, b)根本不会被求值,编译器也就无需检查offsetof的参数是否完整。哪怕后续添加使用shift的代码,到程序运行时A已经是完整类型,offsetof的使用也会变成合法的。
内容的提问来源于stack exchange,提问作者Alexander S
相关产品推荐
相关产品推荐

