这是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)明确地向结构栏添加默认可见性,即我有
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)包含完全相同的符号和完全相同的修饰符(全局,本地等),只有几个条目第一列(虚拟地址)不同。
答案 0 :(得分:1)
在这两种情况下,显式可见性属性是在每个类的基础上使警告静音的预期方法。来自gcc/cp/decl2.c
:
/* Don't warn about visibility if the class has explicit visibility. */
if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
vis = VISIBILITY_INTERNAL;