我正在写一个库:一些符号将由用户使用,而另一些则是内部烹饪。我开始在GCC Wiki的this page之后使用“可见性”属性,但在某些情况下我不太清楚该属性的作用:

#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。如果我向他们添加可见性属性,那意味着什么?换句话说,当我在m_links中添加TATO_SYM_INTERNAL时,GCC会做什么?
第三,隐藏已删除成员函数的可见性有什么意义吗?

最佳答案

首先,internal可见性为slightly dangerous。考虑改用hidden可见性,哪种更安全。

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

由于m_linksm_offsets已经是私有的,因此外部代码无法访问它们。更重要的是,它们没有链接器符号,因此没有隐藏的内容。应用此属性将无效。

对于诸如复制构造函数之类的已删除成员函数也是如此。这些函数没有在任何地方实现(它们不能在任何地方实现),因此它们没有链接器符号,因此可见性属性不起作用。

关于gcc - 在这些情况下,隐藏的GCC可见性有什么作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13132046/

10-13 09:52