Ответ 1
Я думаю, что оба они ошибаются в С++ 17 1 и что ожидаемый результат должен быть:
4294967295 0
Это, однако, трудно понять из стандарта...
В стандарте написано - [facet.num.get.virtuals # 3.3]:
Последовательность символов, накопленных на этапе 2 (поле), преобразуется в числовое значение по правилам одной из функций, объявленных в заголовке
<cstdlib>
:
Для знакового целочисленного значения используется функция
strtoll
.Для целочисленного значения без знака функция
strtoull
.Для значения с плавающей точкой функция
strtold
.
Поэтому мы возвращаемся к std::strtoull
, который должен возвращать 2ULLONG_MAX
и не устанавливать errno
в этом случае (что и делают оба компилятора).
Но в том же блоке (акцент мой):
Числовое значение, которое необходимо сохранить, может быть одним из следующих:
ноль, если функция преобразования не преобразует все поле.
самое положительное (или отрицательное) представимое значение, если поле, которое должно быть преобразовано в целочисленный тип со знаком, представляет собой слишком большое положительное (или отрицательное) значение, которое должно быть представлено в
val
.самое положительное представимое значение, если поле, которое должно быть преобразовано в целочисленный тип без знака, представляет значение, которое не может быть представлено в
val
.преобразованное значение, в противном случае.
Полученное числовое значение сохраняется в
val
. Если функция преобразования не преобразует все поле, или если поле представляет собой значение вне диапазона представимых значений,ios_base::failbit
присвоенныйerr
.
Обратите внимание, что все эти разговоры о "поле, которое нужно преобразовать", а не фактическое значение, возвращаемое std::strtoull
. Поле здесь на самом деле является расширенной последовательностью символов '-', '1'
.
Поскольку поле представляет значение (-1), которое не может быть представлено unsigned
, возвращаемое значение должно быть UINT_MAX
а failbit должен быть установлен на std::cin
.
1clang
был фактически прав до С++ 17, потому что третья пуля в приведенной выше цитате была:
- самое отрицательное представимое значение или ноль для целого числа без знака, если поле представляет слишком большое значение, которое должно быть представлено в
val
.ios_base::failbit
присваиваетсяerr
.
2 std::strtoull
возвращает ULLONG_MAX
потому что (спасибо @NathanOliver) - C/7.22.1.4.5:
Если субъектная последовательность имеет ожидаемую форму и значение базы равно нулю, последовательность символов, начинающихся с первой цифры, интерпретируется как целочисленная константа в соответствии с правилами 6.4.4.1.[...] Если последовательность объектов начинается с знака минус, значение, полученное в результате преобразования, отменяется (в возвращаемом типе).