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

谁能解释一下为什么添加两个字符(或两个无符号短裤)会产生 int?它是编译器错误还是符合标准?

谢谢。

4

3 回答 3

26

您所看到的是算术表达式期间发生的所谓“通常算术转换”的结果,尤其是那些本质上是二进制的(带两个参数)。

这在 §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 intunsigned int则应将 a 转换为 a long int;否则两个操作数都应转换为unsigned long int.
— 否则,如果任一操作数为long,则另一个应转换为long
— 否则,如果任一操作数为unsigned,则另一个应转换为unsigned

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

§4.5 中提到的促销活动是:

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

2 类型wchar_t(3.9.1) 或枚举类型 (7.2) 的右值可以转换为以下第一种类型的右值,这些类型可以表示其基础类型的所有值:intunsigned intlongunsigned long

int3如果int可以表示位域的所有值,则整数位域 (9.6) 的右值可以转换为类型的右值;否则,它可以转换为unsigned int如果unsigned int可以表示位域的所有值。如果位域更大,则不会对其应用积分提升。如果位字段具有枚举类型,则出于提升目的,将其视为该类型的任何其他值。

4 类型的右值bool可以转换为类型的右值intfalse变为零和trueone

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

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

加法的结果是一个右值,如果需要,它会隐式提升为 int 类型,并且如果 int 可以包含结果值。在 sizeof(int) > sizeof(char) 的任何平台上都是如此。但请注意 char 可能会被编译器视为已签名的 char 的事实。

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

于 2011-01-27T09:43:29.273 回答