問題タブ [integer-promotion]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - コンパイラに依存しない式の算術変換と整数の昇格
次のタイプの変数を使用した割り当てがあるとします。
uint64 = uint16 + uint16 + uint32 + uint64
すべての作業が uint64 を使用して行われている限り、結果の r 値が uint64 内に収まることがわかっていると仮定します。
コンパイラは、標準の C 規則に従って計算を行う前に、2 つの uint16 と uint32 を暗黙的に uint64 に昇格させますか?
すなわち
1.)uint64 = uint16 + uint16 + uint32 + uint64
2.)uint64 = uint64 + uint64 + uint64 + uint64
具体的には、次のスニペットの 2 番目のステートメントを適用します。
両方のオペランドが同じ型の場合、それ以上の変換は必要ありません。
それ以外の場合、両方のオペランドが符号付き整数型であるか、または両方が符号なし整数型である場合、整数変換ランクが小さい型のオペランドは、ランクが大きいオペランドの型に変換されます。
それ以外の場合、符号なし整数型のオペランドのランクが他のオペランドの型のランク以上である場合、符号付き整数型のオペランドは符号なし整数型のオペランドの型に変換されます。
それ以外の場合、符号付き整数型のオペランドの型が符号なし整数型のオペランドの型のすべての値を表すことができる場合、符号なし整数型のオペランドは符号付き整数型のオペランドの型に変換されます。
それ以外の場合、両方のオペランドは、符号付き整数型のオペランドの型に対応する符号なし整数型に変換されます。
または、その規則は算術式の直接の lhs と rhs のみに適用され、2 つの uint16 の加算が最初に計算され、結果がわかるまで型が昇格されず、次に uint32 に昇格され、この結果uint64などに昇格...
すなわち
1.)uint64 = uint16 + uint16 + uint32 + uint64
2.)uint64 = (((uint16 + uint16) + uint32) + uint64)
3.)uint64 = ((uint32 + uint32) + uint64)
4.)uint64 = (uint64 + uint64)
これを解決する可能性のあるC標準ルールも教えてください。
c - char を印刷するときに、どの統合プロモーションが行われますか?
私は最近それを読みました
フォーマット指定子 %u により、printf は unsigned int を予期するため、未定義の動作を呼び出します。それでも、この例で何が起こっているのかを理解したいと思います。
printf("%u",x)
で表される式と値で整数昇格規則が適用されると思いますx
。
A.6.1 インテグラル昇格
文字、short 整数、または整数ビットフィールド (すべて符号付きかどうかに関係なく)、または列挙型のオブジェクトは、整数を使用できる式で使用できます。int が元の型のすべての値を表すことができる場合、値は int に変換されます。それ以外の場合、値は unsigned int に変換されます。このプロセスは統合プロモーションと呼ばれます。
ここでいう「使える」とは?「構文的に正しい」または「動作が定義されている」という意味ですか?
そして、この例で x はどのように昇格されますか? int に昇格されることを読みましたが、printf("%u", (int x))
まだ未定義の動作である場合、その理由がよくわかりません...
c - (int64_t)-1 + (uint32_t)0 が署名されているのはなぜですか?
(int64_t)-1 + (uint32_t)0
C で署名されているのはなぜですか? のように見えますint64_t
が、私の直感ではuint64_t
.
参考までに私が走るとき
次の出力が得られます。
c++ - C/C++ が自動的に char/wchar_t/short/bool/enum 型を int に変換するのはなぜですか?
したがって、私がそれをよく理解していれば、整数昇格は次のことを提供します。char, wchar_t, bool, enum, short
型は常にint
(またはunsigned int
) に変換されます。次に、式に異なる型がある場合、さらに変換が適用されます。
私はこれをよく理解していますか?
はいの場合、私の質問: なぜ良いのですか? なんで?不要にならchar/wchar_t/bool/enum/short
ない?たとえば、次のようになります。
前に説明したように、char
ALWAYS は に変換されるint
ため、この場合、自動変換後は次のようになります。
char
しかし、そのタイプが私のニーズに十分であることがわかっている場合、なぜこれが良いのか理解できません。
c - 2 つの uint8_t を追加するときの変換警告
私は次のCコードを持っています:
を使用してこのコードをコンパイルするとgcc -Wconversion
、次の警告が表示されます。
誰かがこの警告が表示される理由を説明できますか? 3 つの変数はすべて typeであるため、 がどこから来るuint8_t
のかよくわかりません。int
c - 整数の昇格、C での変換に関するまだ質問
このトピックは、多くのコンテキストで頻繁に議論されてきました。いくつかの投稿を検索して読んだとき。次の投稿で混乱しました。
以下は元の質問です。
答えは単に「6.3.1.8 通常の算術変換」のポイント 3、つまり、
それ以外の場合、符号なし整数型のオペランドのランクが他のオペランドの型のランク以上である場合、符号付き整数型のオペランドは符号なし整数型のオペランドの型に変換されます。
ただし、私の理解が正しければ、「通常の算術変換」を検討する前に整数昇格を行う必要があります。
そしてそのためのルールは
int が元の型のすべての値を表すことができる場合、値は int に変換されます。それ以外の場合は、 unsigned int に変換されます。これらの変換規則は積分昇格と呼ばれます
つまり、加算はunsigned intよりもsigned intの型で完了することを意味します。また、 unsigned intの結果に負を代入すると、大きな値への変換が発生します。
私は自分の理解に少し自信がありません。誰かがその投稿について同様の混乱を抱えていますか?
返信やコメントは大歓迎です。よろしくお願いします!
ジェフ
c - `uint_fast32_t` は少なくとも `int` と同じ幅であることが保証されていますか?
C 標準では、より小さい整数オペランドは、算術演算が実行される前int
に昇格されると指定されています。int
結果として、より小さい 2 つの符号なし値に対する操作int
は、符号なしではなく符号付きの演算で実行されます。32 ビット オペランドの操作が符号なし数学を使用して実行されることを保証することが重要な場合 (たとえば、積が 2⁶³ を超える可能性のある 2 つの数値を乗算する場合)、型の使用は、uint_fast32_t
未定義の動作なしで符号なしセマンティクスを生成するために、標準によって保証されます。 ? そうでない場合、少なくとも 32 ビットで、int
少なくとも
c - uint8_t の 2 つのシフトを組み合わせると異なる結果が生じるのはなぜですか?
誰かが私に理由を説明できますか:
と:
Cで異なる答えを生成しますか? x
*uint8_t* 型 (符号なし 1 バイト長整数) です。たとえば128 (10000000)
、最初のケースで渡すと返されますが0
(最上位ビットが脱落すると予想されます)、2番目のケースでは元の が返されます128
。何故ですか?これらの式は同等であると思いますか?