我有一些非常简单的代码:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream is("1.0 2.0 1e-500 1e500 12.0");
double d = {17.0, 17.0, 17.0, 17.0, 17.0};
for (int i=0; i < 5; ++i)
{
if (is >> d[i])
{
cout<<"Conversion succeeded"<<endl;
}
else
{
cout<<"Conversion failed"<<endl;
is.clear();
}
}
for (int i=0; i < 5; ++i) cout<<d[i]<<endl;
}
Run Code Online (Sandbox Code Playgroud)
当我使用g ++ 4.1.2编译此代码并在Redhat 5.10(相同的编译器)上运行时,我得到输出:
Conversion succeeded
Conversion succeeded
Conversion failed
Conversion failed
Conversion succeeded
1
2
0
17
17
12
Run Code Online (Sandbox Code Playgroud)
当我在Redhat Linux 6.5(编译器4.4.7)上执行相同的二进制文件时,我得到了
Conversion succeeded
Conversion succeeded
Conversion succeeded
Conversion failed
Conversion succeeded
1
2
0
1.79769e+308
12
Run Code Online (Sandbox Code Playgroud)
预期的行为是什么?下溢在4.4.7上成功,但在4.1.2上失败.溢出在4.4.7上失败(但仍然改变了值)并且在4.1.2时没有改变任何内容而失败.
行为是不确定的还是仅仅是不正确的?
根据 C++11 22.4.2.1.2,转换应该因溢出而失败,但不会因下溢而失败。在溢出的情况下,它仍然应该给出最大可表示值以及设置的值failbit。
因此,您最新的编译器具有正确的现代行为。
然而,这两个古老的编译器都比 C++11 早很多年。在早期的标准中,转换被指定为如果scanf愿意则给出错误;并且在出现错误时不给出值。转向 C 标准,scanf遵循strtod,它又指定溢出错误;但下溢是否有错误是实现定义的。
所以你的旧编译器与历史行为是一致的。
| 归档时间: |
|
| 查看次数: |
95 次 |
| 最近记录: |