コンパイラはsmallValue * value
を確認すると、入力データ型signed
(8 ビット) およびunsigned int
(通常は 16 ビットまたは 32 ビット) を考慮して、結果のデータ型を決定する必要があります。C++ の規則では、この状況では結果が符号なしになると規定されています。したがって、期待どおり、 の値を にすることはsmallValue * value
できません。-500
代わりに、値-500
は正の数値として解釈されます。
さらに、ここでは 8 ビット値に通常 16 ビットまたは 32 ビットのいずれかの値を掛けています。このシナリオでの C++ の規則では、小さい方のストレージ値が最初に大きい方の値と同じサイズにキャストされると規定されています。したがって、この場合、 の結果smallValue * value
は確かに大きさの大きさを格納するのに十分な大きさになり500
ます。
符号なしの量anotherSmallValue
(=1)を乗算するunsigned
と、同じ値の別の値が得られます。
を使用しているためauto
、戻り値の型は と推定されますunsigned
。
にキャストバックするだけでsigned
(たとえば、値test
をint
ではなくとして定義すると、通常は、内部でビットを変更することなくauto
、操作全体の結果が値にキャストされます。これにより、 が適切に表示されます。ただし、他の投稿者が指摘しているように、これは理論的にはかなり危険です。これは、現在のコンパイラでは通常このように動作しますが、技術的に動作することが保証されていないためです。signed
-500