2つの符号なし8ビット値を取り、それらを減算して、この値を32ビットアキュムレータに追加する必要があります。 8ビットの減算はアンダーフローする可能性があります(unsigned intのアンダーフローは定義された動作なので問題ありません)。式のstatic_castが分散して動作するのはなぜですか?
static_cast<uint32_t>(foo - bar)
は、私が欲しいと思うことを期待しています(foo
とbar
はともにuint8_t
です)。しかし、これが最初にキャストし、と表示され、は32ビットの減算を行いますが、8ビットの変数としてアンダーフローする必要があります。私はちょうど256をmodすることができることを知っていますが、私はを理解しようとしていますなぜこの方法で動作します。ここ
uint8_t foo = 5;
uint8_t bar = 250;
uint8_t diff8bit = foo - bar;
uint32_t diff1 = static_cast<uint32_t>(diff8bit);
uint32_t diff2 = static_cast<uint32_t>(foo) - static_cast<uint32_t>(bar);
uint32_t diff3 = static_cast<uint32_t>(foo - bar);
printf("diff1 = %u\n", diff1);
printf("diff2 = %u\n", diff2);
printf("diff3 = %u\n", diff3);
出力:
diff1 = 11
diff2 = 4294967051
diff3 = 4294967051
私はdiff3
がdiff1
と同じ動作を持っているでしょう疑うだろうが、それは実際にdiff2
と同じです。
これはどうしてですか?コンパイラが2つの8ビット値を減算してから32ビットにキャストしなければならないと言うことができる限り、明らかにそうではありません。これは、static_cast
が式でどのように動作するかの仕様と関係していますか?
よりも狭い精度で直接計算を実行することは不可能です。これは 'static_cast'ではなく、減算式のために適用されます。 – dyp
なぜdiff2はdiff1と同じだと思いますか? diff2は明らかに二つの 'uint32_t'を使って減算を行っています。 diff3の結果 - コンパイラは正しいことを決定しました(これは正しい答えを与えます)。それが何か他のことをしたいなら、あなたはそれにそれを伝える必要があります。 – mbgda
@mbgda diff3とdiff1が同じであることを期待しています。 –