コンパイラは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