我有一段生成以下警告的示例代码(使用带有SP1的VS2008编译器):
警告 C4146:对无符号类型应用一元负运算符,结果仍为无符号
代码:
void f(int n)
{
}
int main()
{
unsigned int n1 = 9;
f(-n1);
}
但是由于函数f
将其参数作为int
,所以这段代码不应该有任何警告信息才对吧?
我有一段生成以下警告的示例代码(使用带有SP1的VS2008编译器):
警告 C4146:对无符号类型应用一元负运算符,结果仍为无符号
代码:
void f(int n)
{
}
int main()
{
unsigned int n1 = 9;
f(-n1);
}
但是由于函数f
将其参数作为int
,所以这段代码不应该有任何警告信息才对吧?
f(-static_cast<int>(n));
-x
中,对x
进行了整数提升,这意味着几乎任何内容都会被提升为int
,但不包括unsigned int
。template<class T>
void f(T x)
{
//somehow print type info about x, e.g. cout << typeid(x).name() or something
}
int main()
{
char x;
f(x);
f(+x);
f(-x);
}
输出:
char
int
int
但是 char
-> int
是整型提升,而 unsigned int
-> int
是一种转换。
标准5.3.1/7
一元运算符-的操作数应具有算术或枚举类型,其结果是其操作数的取反。对于整数或枚举类型的操作数进行整数提升。无符号数的负值通过从2的n(n为提升操作数的位数)中减去其值来计算。结果的类型是提升操作数的类型。
Integral Promotion 4.5/1 的段落
如果int类型可以表示源类型的所有值,则char、signed char、unsigned char、short int或unsigned short int类型的rvalue可以转换为int类型的rvalue;否则,源rvalue可以被转换为unsigned int类型的rvalue。
即,unsigned int不会被提升为int。
这个参数是按值传递的。在函数调用中,f(-n1)在将参数传递给函数之前应用了运算符。因此会出现警告。
(int)(-(unsigned)x)
和-(int)x
并不完全相同,因为如果x是INT_MIN,则对其应用减号是未定义的溢出,而对无符号值进行一元减运算对所有无符号值都是定义良好的。如果我错了,请纠正我。 - Nicholas Wilson