C / C ++での署名付きオーバーフローの検出
一見すると、この質問は整数オーバーフローを検出する方法の複製のように見えるかもしれません。ただし、実際には大幅に異なります。 符号なし整数オーバーフローの検出は非常に簡単ですが、C / C ++での符号付きオーバーフローの検出は実際にはほとんどの人が考えるよりも難しいことがわかりました。 それを行う最も明白でありながら素朴な方法は、次のようになります。 int add(int lhs, int rhs) { int sum = lhs + rhs; if ((lhs >= 0 && sum < rhs) || (lhs < 0 && sum > rhs)) { /* an overflow has occurred */ abort(); } return sum; } これに伴う問題は、C標準によれば、符号付き整数オーバーフローは 未定義の動作であるということです。 言い換えると、標準によれば、符号付きオーバーフローが発生するとすぐに、プログラムはnullポインターを逆参照した場合と同じように無効になります。したがって、上記の事後条件チェックの例のように、未定義の動作を引き起こして、事後にオーバーフローを検出しようとすることはできません。 上記のチェックは多くのコンパイラで機能する可能性がありますが、信頼することはできません。実際、C標準では符号付き整数オーバーフローは未定義であるとされているため、一部のコンパイラ(GCCなど)は上記のチェックを最適化します。、最適化フラグが設定されると、符号付きオーバーフローは不可能であると想定するため、を最適化します。これにより、オーバーフローをチェックする試みが完全に中断されます。 …