2016-11-23 8 views
4

Рассмотрим следующий код:Отличие поведения betwen libstdC++ и LIBC++: оператор >> на 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? Clang?

ответ

2

Из моего понимания, LibC++ прямо здесь, но это не только правильное поведение.

N4140 §20.6.4 [bitset.operators]

Эффекты: Экстракты до N символов из вне. Хранит эти символы во временном объекте str типа basic_string<charT, traits>, затем вычисляет выражение x = bitset<N>(str). Символы извлекаются и сохраняются до тех пор, пока не произойдет одно из следующих событий:

  • N символов были извлечены и сохранены;
  • end-of-file встречается во входной последовательности;
  • следующий символ ввода не является 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 должен быть обнулен или должно быть выбрано вышеупомянутое исключение.

Если исключение не выбрасывается, вы можете проверить, была ли ваша операция успешной (путем проверки возвращаемого потока).

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; 
} 

Выход с помощью г ++ 4.9.3:

before = 1 
Failed to restore bitset from stream. 

 Смежные вопросы

  • Нет связанных вопросов^_^