警告C4309 - 这是什么意思,在这种情况下是否可以忽略?

时间:2015-10-25 18:35:10

标签: c++ visual-studio

使用VS2015

char a = 0xFF;
char b = 0x80;

这两行都给出了warning C4309: 'initializing': truncation of constant value

但是当我在调试器中查看它时,变量确实包含正确的值。

在这种情况下,警告意味着什么?我可以忽略它还是我的代码不好?

3 个答案:

答案 0 :(得分:6)

来自https://csharpeval.codeplex.com/wikipage?title=Usage&referringTitle=Documentation

  

'转换':截断常数值

     

类型转换导致常量超过分配的空间   为了它。您可能需要为常量使用更大的类型。

     

以下示例生成C4309:

     

// C4309.cpp //编译:/ W2

int main()
{
   char c = 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 )

我个人喜欢第一个选项,因为它适用于每个编译器,而#pragma选项特定于MVSC。

<强> EDIT2

当然你总是可以写

char a = -1; //0xFF
char b = -128; // 0x80

但在我看来这不太可读。

答案 1 :(得分:2)

在VS20125中,char默认为signed,因此其范围为-128到+127。要取消警告,请将ab声明为unsigned char,范围为0到255.

答案 2 :(得分:1)

我知道这是一个老话题,但是我想增加一个精度。 就您而言,您只需输入:

char a = '\xff';
char b = '\x80';

它从十六进制转义序列(https://en.cppreference.com/w/c/language/character_constant)创建字符文字(https://en.cppreference.com/w/c/language/escape)。编译器将只创建char而不创建int,然后您将不会收到任何警告。

这在C和C ++的所有版本中均有效。