符号可见性和 gcc 警告

Posted

技术标签:

【中文标题】符号可见性和 gcc 警告【英文标题】:Symbol visibility and gcc warnings 【发布时间】:2018-11-10 23:35:58 【问题描述】:

这是Symbol visibility and namespace的后续问题

我将稍微修改这个示例,因为它与命名空间无关:

namespace MyDSO 
  struct __attribute__ ((visibility ("hidden"))) Foo 
    void bar() 
  ;


struct Bar 
  MyDSO::Foo foo;
;

int main() 

通过gcc example.cpp -o example 编译会在链接问题中吐出警告‘Bar’ declared with greater visibility than the type of its field ‘Bar::foo’

问题:为什么如果我收到警告

a) 为 struct Bar 显式添加默认可见性,即我有

namespace MyDSO 
  struct __attribute__ ((visibility ("hidden"))) Foo 
    void bar() 
  ;


struct __attribute__ ((visibility ("default"))) Bar 
  MyDSO::Foo foo;
;

int main() 

b) 删除隐藏的可见性,为 Bar 添加默认可见性并使用-fvisibility="hidden"编译?

在我看来,最终结果是相同的,事实上,所有二进制文件都完全相同(gcc 7.3.1,还有旧的)。如果我将两个结构分成两个类并用它们构建一个静态库,则符号表(objdump -t -C)包含完全相同的符号和完全相同的修饰符(全局、本地等),只有几个条目第一列(虚拟地址)不同。

【问题讨论】:

【参考方案1】:

在这两种情况下,明确的可见性属性是在每个类的基础上消除警告的预期方式。来自gcc/cp/decl2.c

/* Don't warn about visibility if the class has explicit visibility.  */
if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
  vis = VISIBILITY_INTERNAL;

【讨论】:

以上是关于符号可见性和 gcc 警告的主要内容,如果未能解决你的问题,请参考以下文章

GCC:内部可见性“在现实世界的使用中毫无用处”?

C++:警告:“...”声明的可见性高于其字段“...::<anonymous>”的类型

关于变量的可见性和生命周期

volatile关键字原子性和可见性

volatile可见性和指令重排

可见性原子性和有序性