1. ホーム
  2. c++

[解決済み] 整数オーバーフローが未定義の動作になるのはループのどの時点か?

2023-05-10 12:05:38

質問

これは私の質問を説明するための例で、ここには載せられないもっと複雑なコードを含んでいます。

#include <stdio.h>
int main()
{
    int a = 0;
    for (int i = 0; i < 3; i++)
    {
        printf("Hello\n");
        a = a + 1000000000;
    }
}

このプログラムは、私のプラットフォームでは未定義の動作を含んでいます。 a が3回目のループでオーバーフローするからです。

これで プログラム全体 が未定義の挙動をするのか、それとも オーバーフローが実際に発生した後でのみ ? コンパイラは潜在的に a となります。 はオーバーフローするので、ループ全体を未定義と宣言し、printfsがすべてオーバーフローの前に発生するにもかかわらず、わざわざ実行する必要はないのでしょうか?

(それらが異なっている場合、両方の言語のための答えに興味があるので、異なっていてもCとC++をタグ付けしました)。

どのように解決するのですか?

純粋に理論的な答えに興味があるなら、C++ 標準は "タイムトラベル" に未定義の動作を許可しています。

[intro.execution]/5: 整形式のプログラムを実行する適合する実装は,同じプログラムをもつ対応する抽象機械の実行可能な1つと同じ観測可能な振る舞いを生成しなければならない 抽象機械の対応するインスタンスが,同じプログラム,同じ入力で実行される可能性のあるものと と同じ入力で,抽象機械の対応するインスタンスの可能な実行の一つと同じ観察可能な振る舞いを生成しなければならない。しかし そのような実行が未定義の操作を含んでいる場合,この国際規格は,実行する実装に何も要求しない。 規格は、そのプログラムをその入力で実行する実装に何の要件も課さない(最初の未定義操作に先立つ操作に関しても同様)。

このように、もしあなたのプログラムが未定義の動作を含んでいるならば、あなたの プログラム全体 は未定義です。