我的程序执行将二进制数据写入文件的常见任务,符合某种非文本文件格式。由于我正在写入的数据尚未存在于现有 block 中,而是在运行时逐字节放在一起,因此我使用 std::ostream::put()
而不是 write()
.我认为这是正常程序。
该程序运行良好。它同时使用 std::stringstream::put()
和 std::ofstream::put()
以两位十六进制整数作为参数。但是我得到编译器警告 C4309: "truncation of constant value"(in VC++ 2010) 每当参数到 put()
大于 0x7f。显然编译器期待 signed char
, 常数超出范围。但我认为实际上并没有发生任何截断。字节按预期写入。
编译器警告让我觉得我没有以正常的、可接受的方式做事。我描述的情况必须是常见的。 是否有避免这种编译器警告的常用方法?或者这是一个应该忽略的毫无意义的编译器警告示例?
我想到了两种不优雅的方法来避免它。我可以使用像 mystream.put( char(0xa4) )
这样的语法每次通话。或者不使用 std::stringstream
我可以使用 std::basic_stringstream< unsigned char >
,但我认为该技巧不适用于 std::ofstream
,它不是模板类型。我觉得这里应该有更好的解决方案,尤其是因为 ofstream
用于编写二进制文件。
你的想法?
--编辑--
啊,我弄错了std::ofstream
不是模板类型。实际上是std::basic_ofstream<char>
,但我尝试了那个方法,并意识到由于缺少定义的方法和与 std::ostream
的多态不兼容,它无论如何都行不通。 .
这是一个代码示例:
stringstream ss;
int a, b;
/* Do stuff */
ss.put( 0 );
ss.put( 0x90 | a ); // oddly, no warning here...
ss.put( b ); // ...or here
ss.put( 0xa4 ); // C4309
最佳答案
我找到了令我满意的解决方案。它比将每个常量显式转换为 unsigned char
更优雅。这就是我所拥有的:
ss.put( 0xa4 ); // C4309
我认为“截断”是在将 unsigned char
隐式转换为 char
时发生的,但 Cong Xu 指出整数常量被假定为有符号的,并且任何大于 0x7f 的 1 从 char
提升为 int
。然后如果传递给 put()
,它实际上必须被截断(减少到一个字节)。通过使用后缀“u”,我可以指定一个无符号整数常量,如果它不大于 0xff,它将是一个 unsigned char
。这就是我现在所拥有的,没有编译器警告:
ss.put( 0xa4u );
关于c++ - 有没有一种正统的方法来避免编译器警告 C4309 - "truncation of constant value"与二进制文件输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15467837/