添加两个字符会产生int

时间:2011-01-27 09:34:49

标签: c++ integer integer-overflow integer-promotion

我做了一个简单的程序,用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

有人可以解释一下为什么添加两个字符(或两个无符号短路)会产生int吗? 它是编译器错误还是符合标准?

感谢。

3 个答案:

答案 0 :(得分:24)

您所看到的是在算术表达式中出现的所谓“常规算术转换”的结果,特别是那些本质上是二进制的(带两个参数)。

这在§5/ 9中描述:

  

许多期望算术或枚举类型操作数的二元运算符会以类似的方式导致转换并产生结果类型。目的是产生一个通用类型,它也是结果的类型。此模式称为通常的算术转换,其定义如下:

     

- 如果任一操作数的类型为long double,则另一个操作数应转换为long double
   - 否则,如果任一操作数为double,则另一个操作数应转换为double    - 否则,如果任一操作数为float,则另一个操作数应转换为float    - 否则,应对两个操作数执行整体促销(4.5)。 54)
   - 然后,如果任一操作数为unsigned long,则另一个操作数将转换为unsigned long    - 否则,如果一个操作数是long int而另一个是unsigned int,那么long int可以表示unsigned int的所有值,unsigned int转换为long int;否则两个操作数都应转换为unsigned long int    - 否则,如果任一操作数为long,则另一个操作数应转换为long    - 否则,如果任一操作数为unsigned,则另一个操作数应转换为unsigned

     

[注意:否则,唯一剩下的情况是两个操作数都是int]

§4.5中提到的促销是:

  

1类型charsigned charunsigned charshort intunsigned short int的左值可以转换为{{1}类型的右值如果int可以表示源类型的所有值;否则,源rvalue可以转换为int类型的右值。

     

2类型unsigned int(3.9.1)或枚举类型(7.2)的右值可以转换为以下第一种类型的右值,它可以表示其基础类型的所有值:{ {1}},wchar_tintunsigned int

     

3如果long可以表示位字段的所有值,则可以将积分位字段(9.6)的右值转换为类型unsigned long的右值;否则,如果int可以表示位字段的所有值,则可以将其转换为int。如果位字段较大,则不适用整数提升。如果位字段具有枚举类型,则将其视为该类型的任何其他值以用于促销目的。

     

4类型unsigned int的左值可以转换为unsigned int类型的右值,bool变为零,int变为false

     

5这些转换称为整体促销。

从这里开始,“乘法运算符”或“添加运算符”等部分都有短语:“执行通常的算术转换... “指定表达式的类型。

换句话说,当您进行积分算术时,类型将根据上述类别确定。在您的情况下,促销由§4.5/ 1涵盖,表达式的类型为true

答案 1 :(得分: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

答案 2 :(得分:3)

当您将这两个字符相互添加时,它们首先被提升为int。

添加的结果是一个被隐式提升的右值 必要时输入int,如果int可以包含结果值。 在sizeof(int)&gt;的任何平台上都是如此。的sizeof(char)的。 但要注意char可能被视为签名char的事实 你的编译器。

这些链接可以提供进一步的帮助 - wikisecurecoding