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()。メンバー関数は文書化されておらず、私の喜びのためにここにあるだけです。その場合、シンボルを非表示にすることは理にかなっていますか?

2 番目、m_linksおよびm_offsets. それらに可視性の属性を追加すると、それはどういう意味になりますか? TATO_SYM_INTERNAL別の言い方をすると、m_linksに追加すると GCC は何をしますか?

第三に、削除されたメンバー関数の可視性を隠すことはまったく意味がありますか?

4

1 に答える 1

1

まず、internal視界が少し危険です。hidden代わりに、より安全な可視性を使用することを検討してください。

可視性フラグは、リンカーがシンボルを認識できるかどうかを決定します。ライブラリ外の誰かがallocateメソッドを呼び出そうとすると、メソッドが実装されていないかのようにリンカ エラーが発生します。部外者にメソッドを呼び出させたくない場合はこれで問題ないかもしれませんが、リンカー エラーは通常、コンパイラ エラーよりも混乱を招きます。メソッドを「プライベート」としてマークすることをお勧めします (可能であれば)。これにより、ユーザーのエラー メッセージのエクスペリエンスが向上します。

m_linksとはすでに非公開であるためm_offsets、外部コードがそれらに到達する方法はありません。さらに重要なことに、それらにはリンカー シンボルがないため、隠すものは何もありません。この属性を適用しても効果はありません。

コピー コンストラクターなどの削除されたメンバー関数についても同じことが言えます。関数はどこにも実装されていない (実装できない) ため、リンカー シンボルがないため、可視性属性は何もしません。

于 2014-12-21T01:49:11.203 に答える