4

私の小さな C ライブラリの例を考えてみましょう:

#include <external_library.h>

void some_function(void)
{
    external_library_call();
    // Do other stuff...
}

some_function() をパブリックに呼び出せるようにする予定です。ただし、ライブラリが必要とする外部ライブラリも、たまたま同じプロトタイプを持つ some_function() という関数を使用しているため、ライブラリは機能しません。ただし、GCC のリンカーは、some_function シンボルのソースがいくつあるかは気にしません。一見無作為に 1 つを選択し、外部ライブラリは独自の代わりに my some_function() を使用する場合と使用しない場合があります。これは非常識です。ライブラリが機能しないという事実ではありません。このライブラリは絶対に機能しないはずです。シンボル「some_function」のソースが 2 つありますが、リンカーはそれについて何もしません。そして、ご存知のように、私はGCCに慣れており、Cは一般的にデフォルトで病理学的に無謀であるため、それほど気にしません。方法があるに違いない ただし、同じシンボルに 2 つのソースがある場合にリンカに警告させるためです。-Wall -Wextra -Wshadow は既に試しましたが、警告は表示されません。

両方のライブラリが some_function() をエクスポートしたいので、-fvisibility=hidden はここでは役に立たないことに注意してください。一意のプレフィックスなしで関数呼び出しを行うことで、私を恥ずかしく思うことができます。あなたが正しい。それは間違い。私は気にしない。この間違いはリンカーによってキャッチできるため、キャッチする必要があります。リンカーがこの間違いをキャッチしない理由はありません。さらに、使用しているライブラリは奇妙な予期しないシンボルをエクスポートする可能性があり、他の誰かのライブラリがエクスポートするものを必ずしも制御できるとは限りません。それとプレフィックスは、プログラマーが停止して発火する前に、非常に一意にすることができます。

4

2 に答える 2

1

追加:

-fvisibility=非表示

ビルド フラグに。ただし、いくつかの注意点があります。一部のヘッダーはこれを予期していない可能性があります。そのような場合、それらを含める前にプラグマを使用する必要があります。

#pragma GCC visibility push(hidden)
#include <problematic_header>
#pragma GCC visibility pop

これには、シンボルの衝突を回避する以外にもいくつかの利点があります。見る:

http://gcc.gnu.org/wiki/Visibility

興味のある方はどうぞ。

于 2012-12-21T16:54:32.867 に答える
0

などのオプション-Wall -Wextra -Wshadowは、ソース コードの分析に影響を与えるコンパイラ フラグです。どうやら、あなたはリンカーオプションを求めています。

ただし、shutdown()アプリケーションが使用するために予約されている名前空間にあるため (さらに、 system を宣言するヘッダーをインクルードしたことさえ示していませんshutdown())、コンパイラーまたはリンカーができることはあまりありません。アプリケーション プログラマーは、呼び出された関数を作成してshutdown()呼び出すことができます。LSB (Linux Standards Base) コンプライアンス スイートなどを調べて、実装によって定義されている関数を定義していないことを確認できます。

私がこれまで追跡しなければならなかった難しいバグの 1 つは、別のインターフェイスを_bind()持つシステム関数とたまたま同じ名前のコード内の関数に関係していました。_bind()私たちの関数がシステム ライブラリの一部によって呼び出されたとき、すべての地獄が解き放たれました。これは、システムに予約されている名前を使用した (変数名または関数名を で始めないでください_) ことに対する私たちの責任の一部でした。1 つのプラットフォームだけで名前の衝突があったのは残念でした。_bind()問題を解決するための体系的な接頭辞。

C および POSIX 標準の予約名のリストを見ることができます。ただし、_t接尾辞は予約されていますが、接尾辞付きの型名はユーザー定義型にも広く (ab) 使用されています。また、型の特定の定義が「システム ヘッダーから」(おそらく OK) であるか、ユーザー定義ヘッダーから (おそらく OK ではない) であるか、または「不足しているシステム機能を提供するユーザー定義ヘッダー」であるかを知る必要があります。 (境界線)。とてもトリッキーになります。

于 2012-12-21T17:26:01.510 に答える