libstdc ++和libc ++之间的行为差​​异:运算符>>在bitset上

时间:2016-11-23 07:06:27

标签: c++ gcc clang std std-bitset

请考虑以下代码:

#include <bitset>
#include <sstream>
#include <iostream>

int main(int argc, char* argv[])
{
    std::stringstream stream;
    std::bitset<1> bitset(1);
    std::cout<<"before = "<<bitset[0]<<std::endl;
    stream<<"4";
    stream>>bitset;
    std::cout<<"after = "<<bitset[0]<<std::endl;
    return 0;
}

使用g++libstdc++下编译,结果为:

> g++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty 
before = 1
after = 1

使用clang++libc++下编译,结果为:

> clang++ -stdlib=libc++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty 
before = 1
after = 0

哪一个是对的?两者(因为未定义的行为?)? GCC?铛?

2 个答案:

答案 0 :(得分:2)

您应该检查是否

stream>>bitset;

成功。如果没有,则在此之后您不能指望bitset的值。

#include <bitset>
#include <sstream>
#include <iostream>

int main(int argc, char* argv[])
{
    std::stringstream stream;
    std::bitset<1> bitset(1);
    std::cout<<"before = "<<bitset[0]<<std::endl;
    stream<<"4";
    if ( stream>>bitset )
    {
       std::cout<<"after = "<<bitset[0]<<std::endl;
    }
    else
    {
       std::cout << "Failed to restore bitset from stream.\n";
    }
    return 0;
}

使用g ++ 4.9.3输出:

before = 1
Failed to restore bitset from stream.

答案 1 :(得分:2)

根据我的理解,libc ++就在这里,但它并不是唯一正确的行为。

  

N4140§20.6.4[bitset.operators]

     

效果:从is中提取最多N个字符。将这些字符存储在basic_string<charT, traits>类型的临时对象str中,然后计算表达式x = bitset<N>(str)。   提取并存储字符,直到出现以下任何一种情况:

     
      
  • 已提取并存储了N个字符;
  •   
  • 文件结尾出现在输入序列上;
  •   
  • 下一个输入字符既不是is.widen(’0’)也不是is.widen(’1’)(在这种情况下,输入字符不会被提取)。
  •   
     

如果str中没有存储任何字符,请致电   is.setstate(ios_base::failbit)(可能会抛出ios_base::failure   (27.5.5.4))

重要的是要注意x = bitset<N>(str)不是有条件的。如果没有抛出ios_base::failure,那么这就是执行的表达式。而bitset<N>(""s)(即空字符串)是0

因此,根据我的理解,您的bitset应归零,否则应抛出上述异常。

如果没有抛出异常,您可能想测试您的操作是否成功(通过测试返回的流)。