18

static関数でCのキーワードを使用すると、関数が定義されているコンパイル単位に制限されることを知っています。static現在、シンボルの可視性を調べていますが、関数と、でマークされた関数の違い__attribute__((visibility("hidden")))、または-fvisibility=hiddenコマンドラインオプションの使用について少し混乱しています。

これらが内部で物事を変える方法はまったく同じではないと感じていますが、実際のコードでそれらを操作するときの違いやそれが何を意味するのかはわかりません。2つの間で何が変わり、いつ一方を他方の上に使用したいですか?

4

3 に答える 3

17

の関数__attribute__((visibility("hidden")))は、それを含む共有ライブラリの外では見えませんが、そのライブラリがリンクによって作成された場合、そのfoo.pic.oようbar.pic.oな関数fhidは で定義しfoo.cて から呼び出すことができますbar.c。もちろん、外部コード (メイン プログラムや他の共有ライブラリなど) からはそれを呼び出すことはできません。fhid

したがって、非表示の可視性は、それを構成する個々のコンパイル ユニットではなく、共有ライブラリ全体に適用されます。

対照的に、 で関数を定義し、 で別の関数を定義することは可能でした(たとえfoo.cそれが趣味が悪く、読みやすさの理由から避けるべきであるとしても)。static void fsta(void)bar.c static void fsta(void)

また、原則として、static関数をより簡単にインライン化することも、コンパイラが (場合によっては) 関数に対して異なる呼び出し規則を使用することもできます。

于 2013-02-17T09:04:07.830 に答える
5

共有ライブラリに関数がglobalあり、共有ライブラリのコンテキスト内でのみ使用したいが、共有ライブラリの外では使用したくない場合は、__attribute__((visiblity("hidden")))

例えば:

void foo()で定義された関数があり、Foo.cそれを参照してBar.cBaz.c生成するコンパイル単位FooBarBaz.dll(または FooBarBaz.so) を指定する場合は、関数を次のように作成できます。

__attribute__((visibility("hidden"))) void foo() {}

(または .so ファイル) をロードする実行可能ファイルには表示されないことに注意してください。このペーパーfoo()読むdll

于 2013-02-17T09:11:30.110 に答える
0

非表示の可視性は、シンボルが動的シンボル テーブルに配置されないことを示しているため、他の「モジュール」(実行可能ライブラリまたは共有ライブラリ) はそれを直接参照できません。

http://ohse.de/uwe/articles/gcc-attributes.html

追加できます: __attribute__((visibility("hidden")))C のバージョンの に近いセマンティクスを持つ C++ で使用できますstatic

于 2013-02-17T09:06:26.510 に答える