Решил я сегодня первый раз воспользоваться функцией
std::from_chars и не понял как правильно проверять результат вызова.
Дело в том, что в случае успеха "ec is value-initialized", где ec это поле from_chars_result:
struct from_chars_result {
const char* ptr;
std::errc ec;
};
При этом std::errc определяется в стандарте как
enum class errc {
address_family_not_supported, // EAFNOSUPPORT
....
При этом в MS компиляторе определение такое:
// ENUM CLASS errc
enum class errc
{ // names for generic error codes
address_family_not_supported = 102, // EAFNOSUPPORT
...
Если я правильно понимаю, "ec is value-initialized" означает инициализацию вида
errc{}.
Внимание вопрос: какое значение будет у ec в случае успешного выполнения?
Я вижу возможные варианты:
1) unspecified
2) undefined behavior
3) 0
4) errc::address_family_not_supported
Так как у errc не указан underlying type, то если я правильно помню, присваивание любого значения лежащего вне перечисленных — это undefined behavior. Это так? Если так, то либо у
address_family_not_supported == 0, либо
errc{} != 0.
Короче: с чем, согласно стандарту, следует сравнивать значение std::errc{} ?
Здравствуйте, B0FEE664, Вы писали:
BFE>Решил я сегодня первый раз воспользоваться функцией std::from_chars и не понял как правильно проверять результат вызова.
BFE>Если я правильно понимаю, "ec is value-initialized" означает инициализацию вида errc{}.
BFE>Внимание вопрос: какое значение будет у ec в случае успешного выполнения?
Чем первая строка из примера документации не нравится?
if (ec == std::errc())
{
std::cout << "Result: " << result << ", ptr -> " << std::quoted(ptr) << '\n';
}
Здравствуйте, Igore, Вы писали:
BFE>>Решил я сегодня первый раз воспользоваться функцией std::from_chars и не понял как правильно проверять результат вызова.
BFE>>Если я правильно понимаю, "ec is value-initialized" означает инициализацию вида errc{}.
BFE>>Внимание вопрос: какое значение будет у ec в случае успешного выполнения?
I>Чем первая строка из примера документации не нравится?
I>I> if (ec == std::errc())
I> {
I> std::cout << "Result: " << result << ", ptr -> " << std::quoted(ptr) << '\n';
I> }
I>
Ничем не нравится:
Откуда следует, то это не undefined behavior?
Какое значение у std::errc()?
Откуда следует, что оно не совпадает ни с каким значение ошибки?
Относительно undefined behavior:
Если посмотреть в дебагере, то у std::errc() значение 0, но этого значения нет в перечислении. При этом:
If the enumeration type does not have a fixed underlyingtype, the value is unchanged if the original value is within the range of the enumeration values (9.7.1), and otherwise, the behavior is undefined.
это из 7.6.1.8/10 С++17
Мне не понятно, что такое the range of the enumeration values. У него крайне смутное описание:
9.7.1/8
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, the values of the enumeration are the values representable by a hypothetical integer type with minimal width M such that all enumerators can be represented. The width of the smallest bit-field large enough to hold all the values of the enumeration type is M. It is possible to define an enumeration that has values not defined by any of its enumerators. If the enumerator-list is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0.
Мне совсем не сложно представить гипотетический целый тип состоящий из двух бит и принимающий значения (3,4,5,6) для перечисления
enum class X{ a=3, b=4, c=5, d=6 }; Нуля среди них нет, значит 0 — вне диапазона. Или же где-то сказано, про какие-то ограничения на гипотетические целые типы?
Ладно, предположим, что 0 всегда допустимое значение для перечисления (хотя я пока не вижу откуда это следует), тогда откуда можно узнать,
errc{} не совпадает ни с каким значением этого перечисления?
Здравствуйте, B0FEE664, Вы писали:
BFE>Если я правильно понимаю, "ec is value-initialized" означает инициализацию вида errc{}.
BFE>Внимание вопрос: какое значение будет у ec в случае успешного выполнения?
BFE>Я вижу возможные варианты:
BFE>1) unspecified
BFE>2) undefined behavior
BFE>3) 0
BFE>4) errc::address_family_not_supported
Я думаю (3):
https://stackoverflow.com/questions/53897991/enum-class-default-initialization
Как описанно по ссылки auto x = errc() эквиванетно auto x = static_cast<errc>(0).
BFE>Так как у errc не указан underlying type, то если я правильно помню, присваивание любого значения лежащего вне перечисленных — это undefined behavior. Это так? Если так, то либо у address_family_not_supported == 0, либо errc{} != 0.
По идее только если значение не может уместиться в "underlying type" то это UB, а 0 всегда может уместиться
в "underlying type":
https://stackoverflow.com/questions/33812998/is-it-allowed-for-an-enum-to-have-an-unlisted-value
см. последний комментарий.