我做了一个简单的程序,用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吗? 它是编译器错误还是符合标准?
感谢。
答案 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类型
char
,signed char
,unsigned char
,short int
或unsigned short int
的左值可以转换为{{1}类型的右值如果int
可以表示源类型的所有值;否则,源rvalue可以转换为int
类型的右值。2类型
unsigned int
(3.9.1)或枚举类型(7.2)的右值可以转换为以下第一种类型的右值,它可以表示其基础类型的所有值:{ {1}},wchar_t
,int
或unsigned 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的事实 你的编译器。
这些链接可以提供进一步的帮助 - wiki和securecoding