コンパイラの最適化と未定義の動作: C ではブール値に関する特定の仮定を許可しますか?
はじめに
この記事では、C 標準がコンパイラに次のことを想定することを許可しているかどうかを検証します。ブール値の特定の数値表現と、そのような仮定がプログラムのクラッシュなどの結果を引き起こす可能性があるかどうか。
問題
プログラマーが初期化されていないブール値を使用中にプログラムのクラッシュに遭遇しました。ブール値を文字列にシリアル化する関数内。驚くべきことに、このクラッシュは、最適化が有効になっている特定のコンパイラを使用している特定のプラットフォームでのみ発生しました。
問題のあるコード:
void Serialize(bool boolValue) { const char* whichString = boolValue ? "true" : "false"; const size_t len = strlen(whichString); memcpy(destBuffer, whichString, len); }
コードが Clang 5.0.0 と最適化で実行された場合 ( -O2)、クラッシュする可能性があります。この動作は、文字列 "true" と "false" の長さが 1 だけ異なるというオプティマイザの推論により発生します。実際の長さを計算する代わりに、boolValue の値が 0 または 1 であると仮定して使用されます。
const size_t len = strlen(whichString); // original code const size_t len = 5 - boolValue; // clang optimization
質問: 標準的な考慮事項
この記事は次のような質問を提起しています: C 標準では、コンパイラーは bool が内部数値表現「0」または「1」のみを持つことができると想定し、そのような方法で使用することを許可していますか?それとも、これは、実装がすべてのブール値に 0 または 1 のみが含まれ、その他の値は未定義の動作領域であると想定している、実装定義の動作のケースですか?
回答: 標準準拠
著者によると、ISO C ではこれを実現する実装が許可されています (ただし、必須ではありません)。 ISO C では、ブール値の内部表現が何であるかを未指定のままにし、実装が独自の仮定を立てることができます。
コンパイラの最適化動作
System V ABI: System V ABI を使用するプラットフォーム用。 x86-64 システムでは、関数に渡される bool 引数は、レジスタの下位 8 ビットの 0 = false および 1 = true のビット パターンで表されます。メモリ内では、bool は 1 バイトの型であり、0 または 1 の整数値を持つ必要があります。
この ABI の決定により、コンパイラは bool に 0 または 1 を想定し、ビット単位で実行するなどの最適化を利用できるようになります。コストのかかる型変換の代わりに操作を実行します。提供されている例では、オプティマイザーはこの動作を利用して strlen(thatString) を 5U - boolValue.
その他の実装と前提:
に最適化しています。System V ABI は広く使用されていますが、他の実装では異なる仮定が行われる可能性があります。たとえば、0 = false、ゼロ以外の値 = true とみなすことができます。このようなシナリオでは、コンパイラは初期化されていない bool 値に対してクラッシュするコードを生成しない可能性がありますが、それでも未定義の動作とみなされる可能性があります。
プログラム クラッシュの危険性
C 標準ではそのような最適化が許可されていますが、未定義の動作に遭遇したプログラムは、その存在全体を通じて完全に未定義であると見なされることに注意することが重要です。これは、実際には呼び出されない関数で未定義の動作が発生した場合でもクラッシュが発生する可能性があることを意味します。
ベスト プラクティスと未定義の動作の回避
コンパイラは、コードの最適化にますます積極的になり、実装についての内部理解に基づいて動作を想定するようになっています。プログラマにとって、実装の仮定に頼ることを避け、移植可能なアセンブリ言語のように動作すると仮定せずにコードが有効な C であることを確認することが重要です。
問題を回避するには、プログラマは次のベスト プラクティスに従う必要があります。
以上がC コンパイラーはブール値の数値表現が 0 または 1 のみであると想定できますか。これにより未定義の動作が発生しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。