Могу ли я проверить встроенный тип во время выполнения? - PullRequest
0 голосов
/ 26 мая 2019

Например,

Если я напишу:

char c = CHAR_MAX;
c++;

Могу ли я узнать, приведет ли 'c ++' к int или char, поэтому я точно знаю, не переполнение ли это?

Ответы [ 2 ]

3 голосов
/ 26 мая 2019

Я не знаю, что вы подразумеваете под «проверкой во время выполнения», но я могу вам точно сказать, что c++ приводит к значению типа char, а c всегда равно char. c никогда не конвертируется в int.

За [expr.post.incr] / 1 :

Значение выражения постфикса ++ является значением его операнда. [ Примечание: Полученное значение является копией исходного значения & Mdash; примечание ] Операнд должен быть изменяемым значением l. тип операнда должен быть арифметическим типом, отличным от cv bool, или указатель на полный тип объекта. Значение объект операнда изменяется путем добавления к нему 1. вычисление значения выражения ++ секвенируется до изменения объект операнда. По отношению к неопределенно-упорядоченной функции вызов, операция postfix ++ является разовой оценкой. [ Примечание: Поэтому вызов функции не должен вмешиваться между Преобразование lvalue в rvalue и побочный эффект, связанный с любым одиночный постфикс ++ оператор. & Mdash; Конечная нота ] В результате получается prvalue. Тип результата - cv-неквалифицированная версия тип операнда . Если операнд является битовым полем, которое не может представляют увеличенное значение, результирующее значение битового поля определяется реализацией. См. Также [expr.add] и [expr.ass].

Как упомянуто Никосом С. в комментарии, вы должны проверить, если c == CHAR_MAX до приращения. Подробнее о проверке переполнения со знаком см. Обнаружение переполнения со знаком в C / C ++ .

2 голосов
/ 26 мая 2019

Могу ли я узнать, приведет ли 'c ++' к int или char

Согласно стандартной цитате в ответе Л.Ф. , вы можете знать, что это приводит к char.

так что я точно знаю, если это не переполнение?

Вы можете точно знать, что это переполнение. На системах, где char является типом со знаком, насколько я могу судить, поведение программы будет неопределенным.

Можно ли проверить встроенный тип во время выполнения?

Вы не можете проверить встроенные типы в время выполнения , но вы можете проверить их уже в время компиляции . Например:

static_assert(std::is_same_v<decltype(c++), char>);

когда я говорю: signed char c = CHAR_MAX + 1 then CHAR_MAX + 1 становится int результатом, а затем в присваивается значение c, которое определяется реализацией.

Действительно. За исключением экзотических систем, где sizeof(signed char) == sizeof(int), в этом случае нет продвижения, а арифметика вызывает переполнение, которое является неопределенным поведением.

И только до C ++ 20. Начиная с C ++ 20, инициализация со знаком с непредставленным значением определяется стандартом.

Могу ли я когда-нибудь переполнить подписанный символ?

Да. Использование оператора приращения. Насколько я могу судить, стандарт ничего не говорит о продвижении в рамках оператора приращения. Однако это может быть открытым для толкования.

...