Nav*_*een 6 c++ unsigned compiler-warnings
我有这个示例代码生成以下警告(带SP1的VS2008编译器):
警告C4146:一元减号运算符应用于无符号类型,结果仍未签名
码:
void f(int n)
{
}
int main()
{
unsigned int n1 = 9;
f(-n1);
}
Run Code Online (Sandbox Code Playgroud)
但是因为函数f正在将它的参数作为一个int不应该编译而没有任何警告吗?
Arm*_*yan 15
if x是类型unsigned int,那么-x它实际上相当于(其中很可能是32).要避免警告并获得正确的行为,请转到:2n-xnint
f(-static_cast<int>(n));
Run Code Online (Sandbox Code Playgroud)
我建议阅读C++标准的"表达式"一章.在那里,你会看到,在表达-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);
}
Run Code Online (Sandbox Code Playgroud)
打印:
char
int
int
Run Code Online (Sandbox Code Playgroud)
但是char- > int是一个完整的促销,而unsigned int- > int是转换
And*_*nck 12
标准5.3.1/7
一元运算符的操作数应具有算术或枚举类型,结果是其操作数的否定.对整数或枚举操作数执行整体提升.通过从2n减去其值来计算无符号数量的负数,其中n是提升的操作数中的位数.结果的类型是提升的操作数的类型.
关于积分促进4.5/1的段落
如果int可以表示源类型的所有值,则可以将char,signed char,unsigned char,short int或unsigned short int类型的rvalue转换为int类型的rvalue.否则,源rvalue可以转换为unsigned int类型的rvalue.
即unsigned int不会被提升为int.