22

簡単なプログラムを作成し、GCC 4.4/4.5 で次のようにコンパイルしました。

int main ()
{
  char u = 10;
  char x = 'x';
  char i = u + x;

  return 0;
}

g++ -c -Wconversion a.cpp

そして、私は次のものを持っています:

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘char’ from ‘int’ may alter its value

次のコードに対して同じ警告が表示されます。

  unsigned short u = 10;
  unsigned short x = 0;
  unsigned short i = u + x;

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its value

2 つの文字 (または 2 つの unsigned short) を追加すると int が生成される理由を誰か説明してもらえますか? それはコンパイラのバグですか、それとも標準に準拠していますか?

ありがとう。

4

3 に答える 3

26

表示されているのは、算術式、特に本質的にバイナリである (2 つの引数を取る) 間に発生する、いわゆる「通常の算術変換」の結果です。

これは§5/9で説明されています:

算術型または列挙型のオペランドを期待する多くの二項演算子は、同様の方法で変換を行い、結果の型を生成します。目的は、結果の型でもある共通の型を生成することです。このパターンは通常の算術変換と呼ばれ、次のように定義されます。

— いずれかのオペランドの型が の場合long double、もう一方は に変換されlong doubleます。
— それ以外の場合、いずれかのオペランドがdoubleの場合、もう一方は に変換されdoubleます。
— それ以外の場合、いずれかのオペランドがfloatの場合、もう一方は に変換されfloatます。
— それ以外の場合、整数昇格 (4.5) は両方のオペランドで実行されます。54)
- 次に、どちらかのオペランドがunsigned longもう一方の場合、 に変換されunsigned longます。
— 一方のオペランドが along intで、もう一方がunsigned intである場合、along intが an のすべての値を表すことができる場合unsigned int、はunsigned inta に変換されlong intます。それ以外の場合は、両方のオペランドが に変換されunsigned long intます。
— それ以外の場合、いずれかのオペランドがlongの場合、もう一方は に変換されlongます。
— それ以外の場合、いずれかのオペランドがunsignedの場合、もう一方は に変換されunsignedます。

[注: それ以外の場合、残りの唯一のケースは、両方のオペランドが であるということですint]

§4.5 で言及されているプロモーションは次のとおりです。

1 型charsigned charunsigned charshort intまたはの右辺値は、ソース型のすべての値を表すことができる場合unsigned short int、型の右辺値に変換できます。それ以外の場合は、ソースの右辺値を type の右辺値に変換できます。 intintunsigned int

2 型wchar_t(3.9.1) または列挙型 (7.2) の右辺値は、基になる型のすべての値を表すことができる次の型の最初の右辺値に変換できます: intunsigned intlong、またはunsigned long

3 整数ビットフィールド (9.6) の右辺値は、ビットフィールドのすべての値を表すことができるint場合、型の右辺値に変換できます。それ以外の場合は、ビットフィールドのすべての値を表すことができる場合intに変換できます。ビットフィールドがさらに大きい場合、整数昇格は適用されません。ビットフィールドに列挙型がある場合、プロモーション目的でその型の他の値として扱われます。 unsigned intunsigned int

4 型の右辺値は、型の右辺値boolに変換できます。ゼロにintなると になります。 falsetrueone

5 これらの変換は、積分昇格と呼ばれます。

ここから、「乗法演算子」や「加法演算子」などのセクションにはすべて、「通常の算術変換が実行されます...」というフレーズがあり、式のタイプを指定します。

つまり、整数演算を行う場合、型は上記のカテゴリで決定されます。あなたの場合、プロモーションは §4.5/1 でカバーされており、式のタイプはintです。

于 2011-01-27T09:57:57.483 に答える
5

型に対して算術演算を実行するcharと、返される結果は int型になります。

これを参照してください:

char c = 'A';
cout << sizeof(c) << endl;
cout << sizeof(+c) << endl;
cout << sizeof(-c) << endl;
cout << sizeof(c-c) << endl;
cout << sizeof(c+c) << endl;

出力:

1
4
4
4
4

ideone でのデモンストレーション : http://www.ideone.com/jNTMm

于 2011-01-27T09:56:17.290 に答える
3

これらの2つの文字を互いに追加すると、最初にintにプロモートされます。

加算の結果は、必要に応じてint型に暗黙的にプロモートされる右辺値であり、intに結果の値を含めることができる場合です。これは、sizeof(int)> sizeof(char)のすべてのプラットフォームに当てはまります。ただし、charはコンパイラによってsignedcharとして扱われる可能性があることに注意してください。

これらのリンクはさらに役立つ可能性があります-wikisecurecoding

于 2011-01-27T09:43:29.273 に答える