質問

次のように、簡単なプログラムを作成し、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つの署名のショートパンツ)を追加する理由がINTを生成する理由を教えてください。それはコンパイラのバグですか、それとも標準的な準拠ですか?

ありがとう。

役に立ちましたか?

解決

あなたが見ているのは、算術表現中に発生するいわゆる「通常の算術変換」の結果、特に本質的にバイナリであるもの(2つの引数を取ります)の結果です。

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

算術または列挙タイプのオペランドが変換を引き起こし、結果タイプを同様の方法で生成する多くのバイナリ演算子が同様の方法で結果タイプを生成します。目的は、共通のタイプを生成することです。これは結果のタイプでもあります。このパターンはと呼ばれます 通常の算術変換, 、次のように定義されています。

- いずれかのオペランドがタイプの場合 long double, 、もう1つはに変換されますlong double.
- それ以外の場合、どちらのオペランドがそうであるか double, 、もう1つはに変換されます double.
- それ以外の場合、どちらのオペランドがそうであるか float, 、もう1つはに変換されます float.
- それ以外の場合、積分プロモーション(4.5)は両方のオペランドで実行されます。54)
- 次に、いずれかのオペランドがそうである場合 unsigned long もう1つはに変換されます unsigned long.
- それ以外の場合、1つのオペランドがaの場合 long int そしてもう一方 unsigned int, 、a long int anのすべての値を表すことができます unsigned int, 、 unsigned int に変換されます long int;それ以外の場合、両方のオペランドを変換するものとします unsigned long int.
- それ以外の場合、どちらのオペランドがそうであるか long, 、もう1つはに変換されます long.
- それ以外の場合、どちらのオペランドがそうであるか unsigned, 、もう1つはに変換されます unsigned.

注:それ以外の場合、残りの唯一のケースは、両方のオペランドが int]

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

1タイプのrvalue char, signed char, unsigned char, short int, 、 また unsigned short intタイプのrvalueに変換できます int もしも int ソースタイプのすべての値を表すことができます。それ以外の場合、ソースrvalueはタイプのrvalueに変換できます unsigned int.

2タイプのrvalue wchar_t (3.9.1)または列挙タイプ(7.2)は、基礎となるタイプのすべての値を表すことができる次のタイプの最初のrvalueに変換できます。 int, unsigned int, long, 、 また unsigned long.

3積分ビットフィールド(9.6)のrvalueは、タイプのrvalueに変換できます int もしも int ビットフィールドのすべての値を表すことができます。それ以外の場合は、に変換できます unsigned int もしも unsigned int ビットフィールドのすべての値を表すことができます。ビットフィールドがまだ大きい場合、統合的なプロモーションはそれには適用されません。ビットフィールドに列挙されたタイプがある場合、プロモーション目的でそのタイプの他の値として扱われます。

4タイプのrvalue bool タイプのrvalueに変換できます int, 、 と false ゼロになります true なりながら one.

5これらの変換は積分プロモーションと呼ばれます。

ここから、」などのセクション乗法演算子" また "添加剤演算子「すべてがフレーズを持っています:」通常の算術変換が実行されます...「式のタイプを指定する。

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

他のヒント

算術操作を行うとき char タイプ、それが返す結果はofです 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

これら2つのキャラクターを互いに追加するとき、彼らは最初にintに昇進します。

追加の結果は、必要に応じてintをタイプするように暗黙的に宣伝され、intが結果の値を含めることができる場合、rvalueです。これは、sizeof(int)> sizeof(char)の任意のプラットフォームで当てはまります。しかし、Charがあなたのコンパイラによって署名されたCharとして扱われるかもしれないという事実に注意してください。

これらのリンクはさらに役立つ可能性があります - ウィキ証券

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top