strcmp
によって返された値を使用しない場合、呼び出しは何も行いません。したがってコンパイラは呼び出しを自由に削除できます。場合によっては、strcmp
が何をするかを正確に知っているので、コンパイラはstrcmp
への呼び出しをインライン展開することもあります。
これは標準ライブラリヘッダで宣言されたすべての識別子(ヘッダが実際に含まれているか否か)留保規格によって容認される:任意の「外部結合を持つすべての識別子:
§ 7.1.3/1 「プログラムがそれで コンテキストで識別子を宣言または定義する場合:常に外部結合を持つ識別子として使用するために予約され
§ 7.1.3/2;次の節[すなわち標準ライブラリヘッダ]&hellipをします。 (7.1.4で許可されている以外の)…その動作は未定義です。
例外として、§ 7.1.4/2: "ライブラリ関数がヘッダーに定義された型を参照することなく宣言できるならば、関数を宣言してそれを使用することも許されますヘッダ。"
独自のstrcmp
を定義すること(スタンドアロンコンパイラを使用しない限り)、明らか未定義の動作であるので、それはおそらく、単純に避けるべきです。しかし、実際には、いくつかの一般的なコンパイラでは移植不可能な方法で行うことが可能です。
最初にstring.h
標準ライブラリヘッダーを含めないでください。 gccで分散、標準Cライブラリのヘッダは__attribute__((pure))
とstrcmp
を宣言:
多くの関数は、戻り値とその戻り値を除いて何の効果を持っていないだけのパラメータおよび/またはグローバル変数に依存します。このような関数は、算術演算子と同じように、共通の部分式消去とループ最適化の対象となることがあります。これらの関数は属性pure
で宣言する必要があります。 (C標準に対する拡張機能です)
この宣言は、関数は(標準出力への書き込み含まれます)は、副作用を持っていないと信じているので、コンパイラはstrcmp
の最初の呼び出しを排除することができます。 gccとclangの両方が、最適化を行わなくても最初の呼び出しを削除します。あなたはstrcmp
に両方の呼び出しをコンパイルするために打ち鳴らすを説得することができます
、あなたは単にstring.h
ヘッダを含む(およびpure
属性なしstrcmp
を自分で宣言)しないことによって排除を回避することができます。しかし、gccはデフォルトでは、多くの標準ライブラリ関数のインラインバージョンの宣言を自動的にインクルードするので(現在のリストはhere in the GCC manualです)、最後のリンクで述べたように、-fno-builtin-strcmp
を追加することで自動宣言を抑制できます。コマンドライン(標準ヘッダを含まない)
組み込み関数が使用されていますか? – 0andriy