8

-WconversionGCC パラメーターは、このプログラムをコンパイルするときに、タイトルから警告を生成します。

#include <iostream>
#include <array>
#include <string>

int main ()
{
    std::string test = "1";
    std::array<unsigned char, 1> byteArray;

    byteArray[0] = byteArray[0] | test[0];

    return 0;
}

コンパイル方法は次のとおりg++- -Wall -Wextra -Wconversion -pedantic -std=c++0x test.cppです。GCC 4.5を使用しています。

私はここで違法なことをしていますか?特定のシナリオで問題を引き起こす可能性はありますか? |が生成するのはなぜintですか?

4

3 に答える 3

6

私はここで違法なことをしていますか?

署名された型から署名されていない型に変換しています。符号付きの値が負の場合、符号なしの結果は実装定義の非負の値になります (したがって、初期値と同じではありません)。

特定のシナリオで問題を引き起こす可能性はありますか?

値が負の可能性がある場合のみ。sizeof (char) == sizeof (int)、またはコードが で 2 つの値を組み合わせるよりも複雑なことを行っている場合は、やや風変わりなアーキテクチャの場合がこれに該当する可能性があります|

|が生成するのはなぜintですか?

すべての整数値は、算術演算で使用される前に昇格されるためです。それらのタイプが より小さい場合int、それらは に昇格されintます。(プロモーションにはそれ以外にも多少のことがありますが、それがこの質問に関連するルールです)。

于 2012-08-20T14:29:54.153 に答える
2

の結果 unsigned char | charは、整数変換ルールintごとです。に再度代入すると、代入によってその値が切り捨てられる可能性があります。コンパイラは、この値がどれくらい大きいかを認識していません。intunsigned charintint

コンパイラを黙らせるには:

byteArray[0] = static_cast<unsigned char>(byteArray[0] | test[0]);

于 2012-08-20T14:30:32.263 に答える
2

はい、文字列は署名された char で構成されています。unsigned char の配列があります。

としては | int を生成することを整数昇格と呼びます。基本的に、コンパイラは両方を int にし、| を実行してから、再び char にします。

しかし、それは問題に遭遇します。C/C++ 標準では、整数昇格は、昇格先の型が昇格元の型のすべての値を保持できる場合に発生します。そのため、unsigned char を unsigned int に昇格させ、signed char を signed int に昇格させます。符号付き値の昇格は、それを符号拡張します。つまり、-1 または 0xFF または 11111111 があるとします。これは 1000000000000000000000001111111 signed int ((int)-1) に拡張されます。明らかに、直感的に期待される 11111111 ((char)-1) で |'ing するのとは異なる結果になります。

詳細については、こちらを参照してください。ここでは、一種の「回避策」について説明しています

于 2012-08-20T14:24:56.120 に答える