g ++和clang ++与流输入和无符号整数的不同行为

时间:2016-04-02 19:31:52

标签: c++ clang++ libstdc++ libc++ istringstream

我遇到了gcc(4.9.2)和clang(3.5.0)之间的行为差​​异,让我感到惊讶。

当我尝试从unsigned int初始化的std::istringstream提供负值(" -15",在示例中)时,我得到了

  • 使用clang ++
  • 发生错误(提出fail()位)
  • 使用gcc ++
  • 初始化signed(-15)

我准备了以下示例程序。

#include <sstream>
#include <iostream>

int main ()
 {
   std::istringstream iss("-15");

   unsigned int  ui;

   iss >> ui;

   std::cout << "ui[" << ui << "] signed(ui)[" << signed(ui)
      << "] flags[" << iss.fail() << iss.good() << iss.bad()
      << iss.eof() << "]\n";

   return 0;
 }

使用clang ++,我获得以下输出

ui[0] signed(ui)[0] flags[1001]

使用g ++,我获得以下输出

ui[4294967281] signed(ui)[-15] flags[0001]

我有两个问题。

第一个是显而易见的:谁是对的? clang ++,g ++还是一个未定义的行为?

第二个是:如何强制gcc ++的行为类似于clang ++,从字母开头用减号提取无符号值时会出错?

谢谢,抱歉我的英语不好。

编辑2016.04.03

我意识到这不是g ++和clang ++之间的区别,而是libstd ++和libc ++之间的区别。

使用clang ++和libstd ++进行编译和链接,获得了与g ++相同的输出。

对不起。

1 个答案:

答案 0 :(得分:1)

此前已讨论过这个问题:Negative numeric string (e.g. "-10") to unsigned short

答案是根据C ++标准22.4.2.1.2p3,转换需要失败,值存储应该是:

  

对于无符号整数类型,最负的可表示值或零,如果该字段表示太大的值,则无法在val中表示。 ios_base :: failbit分配给err。

因此,clang ++是正确的行为。