-Wconversion warning while using operator <<= on unsigned char
-Wconversion warning while using operator <<= on unsigned char
当我用 gcc 编译以下代码时:
int main()
{
unsigned char c = 1;
c <<= 1; // WARNING ON THIS LINE
return 0;
}
我收到此警告:
conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]
为什么?这段代码有什么问题?实际上,我真的可以在 unsigned char
变量上使用运算符 <<=
吗?
编译命令:
g++ test.cpp -Wconversion -o test.exe
这是一个有效的警告:
c <<= 1;
相当于:
c = c << 1
和 <<
的规则说操作数被提升,在这种情况下将被提升为 int
并且结果是提升的类型。所以最后会有一个从 int
到 unsigned char
的转换,这可能会导致值发生变化。
代码有效,警告告诉您正在进行隐式转换,在某些情况下转换可能会改变值。使用强制转换将使警告静音。隐式转换的结果可能非常违反直觉,并且在某些情况下是未定义的行为。见 gcc Wconversion wiki for some details.
如果不手动扩展操作并使用 static_cast
:
,我看不到消除警告的方法
c = static_cast<unsigned char>( c << 1 );
正如我们从这个 gcc bug report 的长线程中看到的那样,并不是每个人都认为这是一个有用的警告案例。
参考 draft C++ standard 部分 5.8
移位运算符:
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand [...]
以及来自第 5.17
节的赋值和复合赋值运算符:
The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is
evaluated only once. [...]
当我用 gcc 编译以下代码时:
int main()
{
unsigned char c = 1;
c <<= 1; // WARNING ON THIS LINE
return 0;
}
我收到此警告:
conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]
为什么?这段代码有什么问题?实际上,我真的可以在 unsigned char
变量上使用运算符 <<=
吗?
编译命令:
g++ test.cpp -Wconversion -o test.exe
这是一个有效的警告:
c <<= 1;
相当于:
c = c << 1
和 <<
的规则说操作数被提升,在这种情况下将被提升为 int
并且结果是提升的类型。所以最后会有一个从 int
到 unsigned char
的转换,这可能会导致值发生变化。
代码有效,警告告诉您正在进行隐式转换,在某些情况下转换可能会改变值。使用强制转换将使警告静音。隐式转换的结果可能非常违反直觉,并且在某些情况下是未定义的行为。见 gcc Wconversion wiki for some details.
如果不手动扩展操作并使用 static_cast
:
c = static_cast<unsigned char>( c << 1 );
正如我们从这个 gcc bug report 的长线程中看到的那样,并不是每个人都认为这是一个有用的警告案例。
参考 draft C++ standard 部分 5.8
移位运算符:
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand [...]
以及来自第 5.17
节的赋值和复合赋值运算符:
The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once. [...]