C では、定数式はコンパイル時に評価される数式です。これらの式を評価する際、未定義動作 (UB) が発生する可能性があるケースを処理することが重要です。
C 標準のセクション 5.19 では、未定義動作の除外を明示的に規定しています。コア定数式:
"...未定義の動作を伴う操作 [...] はありません"
この除外句は 2 つの主な目的を果たします:
次の式を考えてみましょう:
constexpr int x = std::numeric_limits<int>::max() + 1;
除外句がない場合、この式は明示的に除外された操作を含まないため、定数式とみなされます。ただし、整数オーバーフローによる UB は依然として発生します。
以下に示すように、除外句によりコンパイラはコンパイル時にこの UB を検出できます。
error: constexpr variable 'x' must be initialized by a constant expression constexpr int x = std::numeric_limits<int>::max() + 1 ;
除外句を使用すると、SFINAE (置換失敗はエラーではない) で定数式を使用して、式がエラーになるかどうかを判断することもできます。コンパイル時に UB が発生します。たとえば、次のコード スニペットは、整数加算オーバーフローを検出する方法を示しています。
template <typename T1, typename T2> struct addIsDefined { static constexpr bool isDefined() { return isDefinedHelper<T1, T2>(0); } template <T1 t1, T2 t2, decltype(t1 + t2) result = t1 + t2> static constexpr bool isDefinedHelper(int) { return true; } template <T1 t1, T2 t2> static constexpr bool isDefinedHelper(...) { return false; } };
要約すると、定数式に未定義の動作に対する除外句が存在することにより、コンパイラはコンパイル時に UB を検出できるようになり、処理が容易になります。より安全で信頼性の高いコードの開発。
以上がC が定数式から未定義の動作を除外するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。