使用VS2015
char a = 0xFF;
char b = 0x80;
两行都给出了warning C4309: 'initializing': truncation of constant value
但是当我在调试器中查看它时,变量确实包含正确的值。
在这种情况下,警告意味着什么?我可以忽略它还是我的代码坏了?
发布于 2015-10-25 18:40:30
来自https://msdn.microsoft.com/en-us/library/sz5z1byt.aspx
“转换”:常数的截断 类型转换会导致常量超出分配给它的空间。您可能需要对常量使用更大的类型。 以下示例生成C4309: // C4309.cpp //用: /W2编译 int main() { char = 128;// C4309 }
编译器假设您期望0xFF和0x80是正数。就像在这个例子中,它写的是128个,而不是带有-
符号的负数。
所以编译器让您知道char是一个8位的有符号类型,这意味着您的值设置了“符号位”,尽管它没有被标记为负值。
如果变量的符号对您不重要,请使用unsigned char
。这也将删除此警告。
编辑
如果知道自己在做什么,并且故意设置MSB位,则可以使用强制转换来抑制警告:
char a = static_cast<char>(0xFF);
char b = static_cast<char>(0x80);
或使用#pragma
禁用这些行的此特定警告:
#pragma warning( disable : 4309 )
char a = 0xFF;
char b = 0x80;
#pragma warning( default : 4309 )
我个人提出了第一个选项,因为它适用于每个编译器,而#务实选项是针对MVSC的。
EDIT2
当然,你总是可以写
char a = -1; //0xFF
char b = -128; // 0x80
但在我看来,这一点可读性较低。
编辑3
MSVC的新版本似乎也在抱怨static_cast
。要解决这个问题,需要显式地指定所提供的常量号是“unsigned”:
char a = static_cast<char>(0xFFu);
char b = static_cast<char>(0x80u);
更重要的是,在最新版本上,根本不需要铸造。这不带警告地编译:
char a = 0xFFu;
char b = 0x80u;
发布于 2019-08-29 23:10:55
我知道这是个老话题,但我想增加一个精确性。在你的例子中,你可以简单地说:
char a = '\xff';
char b = '\x80';
它从十六进制转义序列(常量)创建字符文字(https://en.cppreference.com/w/c/language/escape)。编译器将只创建一个char
,而不是一个int
,然后您将不会收到警告。
这在C和C++的所有版本中都是有效的。
发布于 2015-10-25 18:38:21
在VS20125中,默认情况下,char
是signed
,因此它的范围是-128到+127。若要取消警告,请将a
和b
声明为unsigned char
,范围为0至255。
https://stackoverflow.com/questions/33333448
复制相似问题