3

複数の文字を保持するchar配列があります。unsigned charこれらの文字の 1 つを変数と比較したいと考えています。例えば:

char myarr = { 20, 14, 5, 6, 42 };
const unsigned char foobar = 133;

myarr[2] = foobar;

if(myarr[2] == foobar){
    printf("You win a shmoo!\n");
}

この比較型は安全ですか?

C99標準からchar、 、signed char、およびunsigned charが 3 つの異なるタイプであることを知っています (セクション 6.2.5パラグラフ 14)。

  • それにもかかわらず、精度を失うことなく、未定義 (または実装定義) の動作を危険にさらすことなく、 との間unsigned charを安全に変換できますか?char

セクション 6.2.5パラグラフ 15 :

実装は、 または のいずれかと同じ範囲、表現、および動作を持つように定義するchar必要があります。signed charunsigned char

セクション 6.3.1.3パラグラフ3:

それ以外の場合、新しい型は署名され、値を表現できません。結果が実装定義であるか、実装定義のシグナルが発生します。

残念ながら、 ifcharが として定義されているsigned char場合、元の値に正しく変換されない実装定義のmyarr[2] = foobar値になる可能性があります。たとえば、関連する値に関係なく、実装は常に値になる場合があります。unsigned char42unsigned

  • これは、同じ型unsignedの変数に値を格納するのは安全ではないということですか?signed

また、実装定義のシグナルとは何ですか。これは、この場合、実装が単にプログラムを終了できることを意味しますか?


セクション 6.3.1.1パラグラフ 1 :

- のランクは のランクlong long intよりも大きく、 のランクよりlong intも大きくなり、intのランクよりもshort int大きくなり、 のランクよりも大きくなりますsigned char

-- 符号なし整数型のランクは、対応する符号付き整数型のランクと同じでなければなりません (存在する場合)。

セクション 6.2.5パラグラフ 8 :

符号が同じで整数変換ランクが異なる 2 つの整数型 (6.3.1.1 を参照) の場合、整数変換ランクが小さい方の値の範囲は、他の型の値の部分範囲になります。

セクション 6.3.1パラグラフ 2 :

intが元の型のすべての値を表すことができる場合、値はint;に変換されます。それ以外の場合は、に変換されますunsigned int

セクション 6.3.1.8パラグラフ 1 :

それ以外の場合、両方のオペランドは、符号付き整数型のオペランドの型に対応する符号なし整数型に変換されます。

の範囲は、またはcharの範囲と同じであることが保証されています。これらは、 との部分範囲であり、整数変換ランクが小さいためです。signed charunsigned charintunsigned int

整数昇格規則でcharは、 、signed char、およびunsigned charが少なくとも評価される前に昇格されることが規定されているため、これは、比較全体でその「署名性」を維持できることをint意味しますか?char

例えば:

signed char foo = -1;
unsigned char bar = 255;

if(foo == bar){
    printf("same\n");
}
  • 明示的なキャストが使用された場合と同等foo == barであっても、偽の値に評価されますか?-1255(unsigned char)

更新

セクション J.3.5パラグラフ1 で、どのケースが実装定義の値と動作になるかについて:

-- 値をその型のオブジェクトで表すことができない場合に、整数を符号付き整数型に変換した結果、またはそれによって生成されたシグナル (6.3.1.3)。

  • これは、明示的な変換でさえ安全ではないということですか?

たとえば、次のコードは符号付き整数型charとして定義できるため、実装定義の動作になる可能性があります。

char blah = (char)255;
4

4 に答える 4

1

char「これは、比較を通じて「署名性」を維持できることを意味しますか?」はい; -1は、その値を保持するsigned charに昇格されます。に関しては、昇格時にその値も保持されるため、はい、比較は false になります。true に評価する場合は、明示的なキャストが必要になります。signed int-1unsigned char255

于 2013-07-25T19:37:22.523 に答える