添加两个字符会产生int

Rom*_*098 21 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;
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我为以下代码得到了同样的警告:

  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
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

GMa*_*ckG 25

您所看到的是在算术表达式期间发生的所谓"常规算术转换"的结果,特别是那些本质上是二进制的(采用两个参数).

这在§5/ 9中描述:

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

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

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

§4.5中提到的促销是:

1型的右边的值char,signed char,unsigned char,short int,或unsigned short int可被转化为式的一个右值int如果int可以表示源类型的所有值; 否则,源rvalue可以转换为类型的右值unsigned int.

2类型的右值wchar_t(3.9.1)或枚举类型(7.2)可以被转换为第一以下类型可以表示其基础类型的所有值的右值:int,unsigned int,long,或unsigned long.

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

4类型的右值bool可以转换为类型的右值int,false变为零并true变为one.

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

从这里开始,诸如" 乘法运算符 "或" 加法运算符 "之类的部分都具有短语:" 执行通常的算术转换... "以指定表达式的类型.

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

  • 对了谢谢。然而我认为 §4.5/1 说的是“可以转换”,而不是“必须”...这是否意味着其他 C++ 编译器可能会生成 char,而不是 int? (2认同)

Naw*_*waz 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;
Run Code Online (Sandbox Code Playgroud)

输出:

1
4
4
4
4

在ideone的演示:http://www.ideone.com/jNTMm

  • @Tomalak Geret'kal:不能保证“sizeof(int)&gt;sizeof(char)”。其基本原理是(据我所知)加法是由 CPU 完成的,而许多 RISC CPU 只执行全角加法。您将以寄存器中的 16 或 32 位值结束。将其限制为“char”宽度将需要额外的操作。 (2认同)