__attribute__((visibility("default"))) 适用于嵌套结构吗?

Does __attribute__((visibility("default"))) apply to nested structures?

当我用 C++ 编写 类 并使用 Pimpl 习惯用法时,我通常设置 结构如下:

Foo.hpp

class Foo
{
public:
    Foo();
    ~Foo();


    void method1();
    void method2();

private:
    struct impl;
    std::unique_ptr<impl> p;
};

Foo.cpp

struct Foo::impl
{
    method1()
    {
        ....
    }
    method2()
    {
        ...
    }

    private_thing()
    {
        ...
    }

}

Foo::Foo():p(make_unique<impl>()){}
Foo::~Foo(){}
void Foo::method1(){ p->method1();}
void Foo::method2(){ p->method2();}

我想隐藏一些实现的符号,所以我 使用 -fvisibility=hidden 编译并添加 __attribute__((visibility("default")))class Foo 定义,像这样:

class __attribute__((visibility("default"))) Foo {...};

我的问题是可见性属性是否适用于方法 嵌套的 impl 结构并使所有成员可见或是否 他们保持隐藏。

检查代码 "nm -CD foo.so",我们可以看到嵌套结构实际上是可见的:

0000000000201048 B __bss_start
                 w __cxa_finalize
0000000000201048 D _edata
0000000000201050 B _end
00000000000009cc T _fini
                 w __gmon_start__
0000000000000780 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
                 U operator delete(void*)
000000000000099c W Foo::impl::method1()
00000000000009a8 W Foo::impl::method2()
00000000000009b4 W Foo::impl::impl()
00000000000009b4 W Foo::impl::impl()
0000000000000960 T Foo::method1()
000000000000097e T Foo::method2()
0000000000000910 T Foo::Foo()
0000000000000910 T Foo::Foo()
0000000000000942 T Foo::~Foo()
0000000000000942 T Foo::~Foo()
                 U operator new(unsigned long)

但是,将 Foo::impl 声明为非嵌套结构 Foo_impl,然后我们得到以下内容:

0000000000201030 B __bss_start
                 w __cxa_finalize
0000000000201030 D _edata
0000000000201038 B _end
000000000000088c T _fini
                 w __gmon_start__
0000000000000668 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
                 U operator delete(void*)
0000000000000820 T Foo::method1()
000000000000083e T Foo::method2()
00000000000007d0 T Foo::Foo()
00000000000007d0 T Foo::Foo()
0000000000000802 T Foo::~Foo()
0000000000000802 T Foo::~Foo()
                 U operator new(unsigned long)

所以看起来是的,可见性说明符实际上确实传播到嵌套结构。