- C++ は移植可能な言語として設計されているためです。つまり、多くの CPU (x86、ARM、LSI-11/2、ゲームボーイ、携帯電話、フリーザー、飛行機、人間操作チップ、レーザー剣などのデバイス) でコンパイルできる言語です。
- CPU 間で使用可能なフラグは大きく異なる場合があります
- 同じ CPU 内であっても、フラグが異なる場合があります (x86 スカラー命令とベクトル命令を使用)
- 一部の CPU には、必要なフラグがまったくない場合があります
- 質問に答える必要があります:コンパイラは、フラグが使用されているかどうかを判断できない場合、常にそのフラグを配信/有効にする必要がありますか? 、これは、C と C++ の両方の書かれていないが神聖な法則を使用するものだけに支払いを適合させるものではありません
- コンパイラは、これらのフラグを有効に保つためにコードを最適化したり、並べ替えたりすることを禁止する必要があるためです。
後者の例:
int x = 7;
x += z;
int y = 2;
y += z;
オプティマイザは、これを疑似アセンブリ コードに変換する場合があります。
alloc_stack_frame 2*sizeof(int)
load_int 7, $0
load_int 2, $1
add z, $0
add z, $1
これは、より似ています
int x = 7;
int y = 2;
x += z;
y += z;
間にレジスタをクエリすると
int x = 7;
x += z;
if (check_overflow($0)) {...}
int y = 2;
y += z;
次に、最適化と逆アセンブルの後、これで終了する可能性があります。
int x = 7;
int y = 2;
x += z;
y += z;
if (check_overflow($0)) {...}
これは正しくありません。
constant-folding-compile-time-overflow で何が起こるかなど、より多くの例を構築できます。
補足: 現在の CPU レジスタを読み取るための小さな API を持つ古い Borland C++ コンパイラを覚えています。ただし、最適化に関する上記の議論は依然として適用されます。
別の補足事項: オーバーフローを確認するには:
// desired expression: int z = x + y
would_overflow = x > MAX-y;
より具体的に
auto would_overflow = x > std::numeric_limits<int>::max()-y;
またはより良い、具体的ではない:
auto would_overflow = x > std::numeric_limits<decltype(x+y)>::max()-y;