符号可见性和 gcc 警告
Symbol visibility and gcc warnings
这是 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) 包含完全相同的符号和完全相同的修饰符(全局、局部等),仅第一列(虚拟地址)中的一些条目不同。
在这两种情况下,明确的可见性属性是在每个 class 基础上消除警告的预期方式。来自 gcc/cp/decl2.c
:
/* Don't warn about visibility if the class has explicit visibility. */
if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
vis = VISIBILITY_INTERNAL;
这是 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) 包含完全相同的符号和完全相同的修饰符(全局、局部等),仅第一列(虚拟地址)中的一些条目不同。
在这两种情况下,明确的可见性属性是在每个 class 基础上消除警告的预期方式。来自 gcc/cp/decl2.c
:
/* Don't warn about visibility if the class has explicit visibility. */
if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
vis = VISIBILITY_INTERNAL;