首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >警告C4309 --这意味着什么,在这种情况下可以忽略它吗?

警告C4309 --这意味着什么,在这种情况下可以忽略它吗?
EN

Stack Overflow用户
提问于 2015-10-25 18:35:10
回答 3查看 5.6K关注 0票数 9

使用VS2015

代码语言:javascript
运行
复制
char a = 0xFF;
char b = 0x80;

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

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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位,则可以使用强制转换来抑制警告:

代码语言:javascript
运行
复制
char a = static_cast<char>(0xFF);
char b = static_cast<char>(0x80);

或使用#pragma禁用这些行的此特定警告:

代码语言:javascript
运行
复制
#pragma warning( disable : 4309 )
char a = 0xFF;
char b = 0x80;
#pragma warning( default : 4309 )

我个人提出了第一个选项,因为它适用于每个编译器,而#务实选项是针对MVSC的。

EDIT2

当然,你总是可以写

代码语言:javascript
运行
复制
char a = -1; //0xFF
char b = -128; // 0x80

但在我看来,这一点可读性较低。

编辑3

MSVC的新版本似乎也在抱怨static_cast。要解决这个问题,需要显式地指定所提供的常量号是“unsigned”:

代码语言:javascript
运行
复制
char a = static_cast<char>(0xFFu);
char b = static_cast<char>(0x80u);

更重要的是,在最新版本上,根本不需要铸造。不带警告地编译:

代码语言:javascript
运行
复制
char a = 0xFFu;
char b = 0x80u;
票数 11
EN

Stack Overflow用户

发布于 2019-08-29 23:10:55

我知道这是个老话题,但我想增加一个精确性。在你的例子中,你可以简单地说:

代码语言:javascript
运行
复制
char a = '\xff';
char b = '\x80';

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

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

票数 3
EN

Stack Overflow用户

发布于 2015-10-25 18:38:21

在VS20125中,默认情况下,charsigned,因此它的范围是-128到+127。若要取消警告,请将ab声明为unsigned char,范围为0至255。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33333448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档