有没有一种正统的方法可以避免编译器警告 C4309 - 带有二进制文件输出的"truncation of constant value"?
Is there an orthodox way to avoid compiler warning C4309 - "truncation of constant value" with binary file output?
我的程序完成了将二进制数据写入文件的常见任务,该文件符合特定的非文本文件格式。由于我正在编写的数据不在现有的块中,而是在运行时逐字节地放在一起,所以我使用std::ostream::put()
而不是write()
。我想这是正常的程序。
这个程序运行得很好。它使用带有两位十六进制整数的std::stringstream::put()
和std::ofstream::put()
作为自变量。但每当put()
的参数大于0x7f时,我就会收到编译器警告C4309:"截断常数值"(在VC++2010中(。显然,编译器期望signed char
,而常量超出了范围。但我认为实际上并没有发生任何截断;字节按照预期写入。
编译器的警告让我觉得我没有以正常的、可接受的方式做事。我所描述的情况一定很常见有没有常见的方法可以避免这样的编译器警告?或者这是一个应该被忽略的毫无意义的编译器警告的例子?
我想了两种不雅的方法来避免它。我可以在每次调用中使用类似mystream.put( char(0xa4) )
的语法。或者,我可以使用std::basic_stringstream< unsigned char >
来代替std::stringstream
,但我认为这个技巧不适用于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
时会发生"截断",但丛旭指出,整数常数被假定为有符号的,任何大于0x7f的常数都会从char
提升为int
。然后,如果传递给put()
,它实际上必须被截断(减少到一个字节(。通过使用后缀"u",我可以指定一个无符号整数常量,如果它不大于0xff,它将是一个unsigned char
。这就是我现在所拥有的,没有编译器警告:
ss.put( 0xa4u );
std::stringstream ss;
ss.put(0x7f);
ss.put(0x80); //C4309
正如您所猜测的,问题是ostream.put()
期望char
,但0x7F
是char
的最大值,任何更大的值都会升级为int
。您应该强制转换为与char
一样宽的unsigned char
,这样它可以安全地存储char
所做的任何事情,但也可以使截断警告合法:
ss.put(static_cast<unsigned char>(0x80)); // OK
ss.put(static_cast<unsigned char>(0xFFFF)); //C4309
- 读取二进制文件时如何输出?
- C++实现代码中的字符串不应存在于输出二进制文件中.如何解决
- 在C 中输出到二进制文件中的麻烦
- 如何获取与 objdump 输出的标签相对应的 ELF 二进制文件中的文件偏移量
- 如何在 c++ 中使用二进制文件输入/输出读取/写入结构的字符串类型成员
- 将对象(指针)在地图中输出到二进制文件
- 如何将std::映射输出到二进制文件
- 读取并输出二进制文件(C++)中位置的字节
- 在线C++编译器:为我输出二进制文件
- 正在读取C++中的二进制文件,并将结果输出为hexdump
- 如何在 C++ 中使用更改光标输入和输出二进制文件
- C ++如何以二进制格式输出Ply文件
- 如何将整数和双精度输出到二进制文件
- 二进制文件中结构的输出返回垃圾
- 用C++将二进制字符串输出到二进制文件
- 自动使输出二进制文件大于命令行编译的二进制文件
- 字节输出到二进制文件c++
- 输出一个写在二进制文件c++中的double
- 从turbo c++中的二进制文件读取后出现意外输出
- 有没有一种正统的方法可以避免编译器警告 C4309 - 带有二进制文件输出的"truncation of constant value"?