C++类成员函数与成员变量使用visibility属性导出符号的差异问题
符号层面类成员函数与成员变量的核心区别
- 非静态成员函数本身是独立的全局符号:类的非静态成员函数会被编译器生成包含类名、参数列表等信息的修饰(mangled)全局唯一符号,它的存储位置独立于任何类实例,编译阶段就可以确定符号地址,因此可以直接应用visibility属性控制符号的导出状态。你代码中类内定义的成员函数哪怕是inline类型,只要添加了default visibility属性,编译器也会为它生成可导出的全局符号。
- 非静态成员变量没有独立的全局符号:非静态成员变量是类实例的一部分,它的地址依赖于具体类对象实例的基地址,只有实例化对象之后才会分配存储空间,本身不存在全局的符号实体。类定义里声明的非静态成员变量只是描述了该成员在类实例内存布局中的偏移量,并不是一个独立的可导出符号。
成员变量visibility属性被忽略的原因
你代码中添加visibility属性的是普通非静态成员变量,它本身就没有独立的全局符号,自然不存在「导出符号」的逻辑,所以编译器会直接忽略这个属性,抛出对应的警告。
如果你的需求是导出类的静态成员变量是可行的,静态成员变量本身是独立的全局符号,只需要把属性加在类外的定义处即可,参考示例:
// a.cpp class A { public: __attribute__ ((visibility("default"))) void func() {;}; static int cnt; // 类内声明无需加属性 }; // 类外定义时添加visibility属性 __attribute__ ((visibility("default"))) int A::cnt = 0;
上述代码编译时不会触发警告,静态成员变量的符号会被正常导出。
内容的提问来源于stack exchange,提问作者velscode
相关产品推荐
相关产品推荐

