3

この質問はおそらく言語弁護士のためのものです。

signedとunsignedintの両方が32ビット幅であると仮定します。n3337.pdfドラフト5.3.1.8に記載されているように、

(-(0x80000000u)) = 0x100000000u-0x80000000u = 0x80000000u

しかし、私は質問に対する答えを見つけることができません:署名された0x80000000の単項マイナスは何になりますか?それはUB、実装定義、または...?

問題は主に実行時の計算に関するものです。

言う

   signed int my_minus(signed int i) { return -i;}
   ....
   int main() {
       signed int a = -0x7FFFFFFF; // a looks like 0x80000001
       signed int b = a - 1;       // b looks like 0x80000000
       std::cout << my_minus(b);
       ....
   }

それでも、他の2つのケースについてのコメントは大歓迎です。

  • コンパイル時定数畳み込み、たとえば、-(INT_MIN)

  • のコンパイル時の計算constexpr(コンパイル時の定数畳み込みとの違いがある場合)。


(重複に投票する前に、 https://meta.stackexchange.com/questions/123713/is-splitting-a-question-a-good-practiceを参照してください。)

4

2 に答える 2

4

私の知る限り、符号付き整数のオーバーフローは常に未定義です。C++ 仕様セクション5 Expressions、段落 4 から:

式の評価中に、結果が数学的に定義されていないか、その型の表現可能な値の範囲内にない場合、動作は未定義です。[注: C++ の既存の実装のほとんどは、整数オーバーフローを無視します。ゼロ除算、ゼロ除数を使用した剰余の形成、およびすべての浮動小数点例外の処理はマシンによって異なり、通常はライブラリ関数によって調整できます。—文末脚注]

于 2012-02-28T03:52:56.253 に答える
3

符号付き整数型は、コンピューターでたらめを追加することなく、数学的な整数の規則に従います。-std::numeric_limits< signed_type >::min()指定された型が結果の数値を表すことができない場合、未定義の動作になります。

では、診断可能なルールとして、未定義の動作を引き起こすものは定数式を無効にするためconstexpr、実装はその式を拒否する必要があります。この場合、ルールは §5.19 の禁止項目の 1 つです。

— 数学的に定義されていないか、そのタイプの表現可能な値の範囲にない結果;

定数の折りたたみでは、コンパイラはオーバーフローした値を挿入する可能性が最も高くなります。

于 2012-02-28T03:50:53.583 に答える