3

我正在写一个库:一些符号是供用户使用的,还有一些是内部烹饪的。我在 GCC wiki 的这个页面之后开始使用可见性属性,但我不太清楚该属性在某些情况下的作用:

#define TATO_SYM_INTERNAL __attribute__((visibility("internal")))
#define TATO_SYM_PUBLIC __attribute__((visibility("default")))

struct linkset
{
public:
    typedef sentence::id      *     iterator;
    typedef const sentence::id   *  const_iterator;

    TATO_SYM_PUBLIC    linkset() ;
    TATO_SYM_INTERNAL  void allocate( const datainfo & _datainfo );
    TATO_SYM_PUBLIC    void addLink( sentence::id _a, sentence::id _b );
    TATO_SYM_PUBLIC    bool areLinked( sentence::id _a, sentence::id _b ) const;
    TATO_SYM_PUBLIC    std::pair<const_iterator, const_iterator> getLinksOf( sentence::id _a ) const;

private:
    typedef std::vector<sentence::id> linksArray;
    linksArray                                  m_links;
    std::vector< std::pair<size_t, size_t> >    m_offsets;

private:
    TATO_SYM_INTERNAL linkset( const linkset & ) = delete;
    TATO_SYM_INTERNAL linkset & operator=( const linkset & ) = delete;
};

inline
void linkset::addLink( sentence::id _a, sentence::id _b ) TATO_RESTRICT
{
  // internal stuff
}

首先,用户没有理由打电话allocate()。成员函数没有记录,它只是为了我的乐趣。在这种情况下,隐藏符号是否有意义?

第二,m_linksm_offsets。如果我为它们添加可见性属性,这意味着什么?换句话说,当我添加TATO_SYM_INTERNAL到 m_links 时,GCC 会做什么?

第三,隐藏已删除成员函数的可见性是否意味着什么?

4

1 回答 1

1

首先,internal能见度有点危险。考虑改用hidden可见性,这样更安全。

可见性标志确定链接器是否可以看到符号。如果您的库之外的人试图调用该allocate方法,他们将收到一个链接器错误,就好像该方法根本没有实现一样。如果您真的不希望外部人员调用该方法,这可能很好,但链接器错误通常比编译器错误更令人困惑。最好将该方法标记为“私有”(如果可能),这将为您的用户提供更好的错误消息体验。

由于m_links并且m_offsets已经是私有的,因此外部代码无法访问它们。更重要的是,它们没有链接器符号,因此没有什么可隐藏的。应用此属性将无效。

对于已删除的成员函数(如复制构造函数)也是如此。这些函数没有在任何地方实现(它们不可能),所以它们没有链接器符号,所以可见性属性什么都不做。

于 2014-12-21T01:49:11.203 回答