Подтвердить что ты не робот

G++ и clang++ различное поведение с потоковым вводом и целым числом без знака

Я столкнулся с различием в поведении, между gcc (4.9.2) и clang (3.5.0), что меня удивило.

Когда я пытаюсь передать unsigned int из std::istringstream, инициализированного отрицательным значением ( "-15", в примере), я получаю

  • ошибка (с выражением fail() бит) с помощью clang++
  • инициализация с помощью signed(-15) с помощью gcС++

Я подготовил тривиальную следующую примерную программу.

#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++ или поведение undefined?

Второй способ: как заставить gcС++ вести себя как clang++, выдавая ошибку при извлечении значения unsigned из строки, начинающейся с минуса?

Спасибо и извините за мой плохой английский.

EDIT 2016.04.03

Я понял, что это не разница между g++ и clang++, но разница между libstd ++ и libС++.

Компиляция и связь с clang++ и libstd ++, я получаю тот же результат, который я получаю с g++.

К сожалению.

4b9b3361

Ответ 1

Об этом было сказано выше: Отрицательная числовая строка (например, "-10" ) до короткой строки без знака

Ответ заключается в том, что в соответствии со стандартом С++ 22.4.2.1.2p3 преобразование требуется для отказа, а хранилища значений должны быть:

самое отрицательное представимое значение или ноль для целых чисел без знака, если поле представляет слишком большое значение, которое должно быть представлено в val. ios_base:: failbit присваивается ошибке.

Следовательно, clang++ - правильное поведение.