stringstream 无符号转换损坏?
考虑这个程序:
#include <iostream>
#include <string>
#include <sstream>
#include <cassert>
int main()
{
std::istringstream stream( "-1" );
unsigned short n = 0;
stream >> n;
assert( stream.fail() && n == 0 );
std::cout << "can't convert -1 to unsigned short" << std::endl;
return 0;
}
我在 OS X 10.5.6 上的 gcc(版本 4.0.1 Apple Inc. build 5490)上尝试过这个程序,断言是正确的; 它无法将 -1 转换为无符号短整型。
然而,在 Visual Studio 2005(和 2008)中,断言失败,n 的结果值与编译器生成的隐式转换所期望的值相同 - 即“-1”是 65535,“-2”是 65534 等但随后“-32769”转换为 32767 就变得很奇怪。
这里谁是对的,谁是错的? (-32769 到底是怎么回事??)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
GCC 在 Max Lybbert 的帖子中声称的行为基于 C++ 标准中的表格,这些表格将 iostream 行为映射到 printf/scanf 转换器(或者至少是我读到的)。 然而,g++的scanf行为似乎与istream行为不同:
实际上打印65535。
The behaviour claimed by GCC in Max Lybbert's post is based on the tables om the C++ Standard that map iostream behaviour onto printf/scanf converters (or at least that;'s my reading). However, the scanf behaviour of g++ seems to be different from the istream behavior:
actually prints 65535.
首先,将字符串“-1”读取为负数取决于区域设置(区域设置可以通过将负数括在括号中来识别负数)。 您的默认标准是“经典”C 语言环境:
根据 GCC 人员的说法,允许数字溢出流输入操作失败(谈论溢出有符号整数的负数):感谢另一个答案,已提交错误并且此行为已更改:
其次,虽然整数溢出通常是可以预测的,但我相信它是 官方未定义的行为,所以虽然我不能说出为什么 -32769” 转换为 32767,但我认为这是允许的。
First, reading the string "-1" as a negative number is locale dependent (it would be possible for a locale to identify negative numbers by enclosing them in parenthesis). Your default standard is the "classic" C locale:
According to the GCC guys, numeric overflow is allowed to fail the stream input operation (talking about negative numbers that overflowed a signed int):Thanks to another answer, a bug was filed and this behavior changed:
Second, although integer overflow is generally predictable, I believe it's officially undefined behavior, so while I can't say why -32769" converts to 32767, I think it's allowed.
试试这个代码:
我在我的 VS2005 上尝试过这个:
在 codepad.org (我认为它使用 g++)上给出:
这告诉我 gcc 使用不同的默认
fmtflags
。 由于fmtflags
控制可能的转换,因此您会得到不同的结果。Try this code:
I tried this on my VS2005:
and on codepad.org (which I think uses g++) this gives:
This tells me that gcc uses a different default
fmtflags
. Sincefmtflags
control what conversions are possible you are getting different results.