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++.
К сожалению.
Ответы
Ответ 1
Об этом было сказано выше: Отрицательная числовая строка (например, "-10" ) до короткой строки без знака
Ответ заключается в том, что в соответствии со стандартом С++ 22.4.2.1.2p3 преобразование требуется для отказа, а хранилища значений должны быть:
самое отрицательное представимое значение или ноль для целых чисел без знака, если поле представляет слишком большое значение, которое должно быть представлено в val. ios_base:: failbit присваивается ошибке.
Следовательно, clang++ - правильное поведение.