C実装(例えば、x86 Cコンパイラ)の場合、USHRT_MAX = 65535
とINT_MAX = 2147483647
とします。次のステートメントは明確に定義されていますか?オーバーフローが発生するので、従って、(int
はunsigned short
のすべての可能な値を表すことができるため)両方のオペランドがint
に昇格されるC99標準で以下とによるintプロモーション:以下は明確に定義されていますか?
unsigned short product = USHRT_MAX * USHRT_MAX;
は、結果は、十分に定義されていません( product
の値が十分に定義されていないことを意味する65535^2 = 4294836225 > 2147483647
):
6.3.1.1-1
int型のCA場合nは元の型のすべての値を表し、値は をintに変換したものです。それ以外の場合は、unsigned intに変換されます。 これは、整数プロモーションと呼ばれます。(48)他のすべてのタイプは整数プロモーションによって変更されずに です。
48)整数キャンペーンのみ適用されます、単項+の オペランドに、特定の引数の式に、通常 算術変換の一部として - 、および〜演算子、 シフトの両方のオペランドに事業者は、それぞれの副次節で指定されているとおりである。
符号なしオペランドを含む計算がオーバーフローしないので、以下に従って、結果は、明確に定義されている:
6.2.5-9
非負の範囲を符号付き整数型の値は対応する符号なし整数型のサブ範囲 であり、各型の同じ値の の表現は同じです。(31)を含む計算結果の符号なし整数型で表される の結果は、 の結果の型で表される最大値よりも1だけ大きい数値である を減じた値になるため、符号なしのオペランドはオーバーフローすることはありません。
上記の文で変数product
は明確に定義された値を持っていますか?
EDIT:次の場合はどうなりますか?
unsigned short lhs = USHRT_MAX;
unsigned short rhs = USHRT_MAX;
unsigned short product = lhs * rhs;
モラル:算術演算に 'int'より小さい型を使用しないでください。ルールは人間の正しいコードを書けるようにあまりにも混乱します。 –
2つのコードには違いはありません。 'int'へのプロモーションは、あなたが定数か変数かを問わずに発生します。 –
ニットのように、最初のケースでは「int」への*プロモーション*はありません。指定された 'USHRT_MAX'は' int 'です。 '65535U'と宣言すれば全体の画像が変わるでしょう。 –