Завершается ли цикл for из-за переполнения unsigned int?

Я готовлюсь к экзамену C, и мне задали этот вопрос:

«Учитывая этот код, завершается ли он? Если да, то почему?»

 int main() {
   unsigned int i;
   for (i=1; i>0; i++);
   return 0;
 }

Я думал, что он завершается из-за характера unsigned int: в цикле for i свободно переходит от 1 к максимальному значению (которое, как я полагаю, равно 2 ^ 32-1), затем цикл сталкивается с исключением переполнения и он возвращается к 0, первому значению беззнакового целого числа. Это противоречит условию цикла i>0 и завершает его, возвращая 0 и завершая программу.

Верна ли моя гипотеза? У нас нет решения, предложенного профессором, поэтому, хотя оно и имеет для меня смысл, оно может быть ужасно неверным, поэтому мне нужна ваша помощь.


person Federico Adragna    schedule 11.01.2020    source источник
comment
Для unsigned int нет исключений. В остальном работает так, как вы описали. Если бы переменная имела тип int, вы бы вызвали Undefined Behavior (не обязательно исключение) при добавлении 1 максимального значения int.   -  person pmg    schedule 11.01.2020
comment
Термин «прекращение» широк. Это может означать, что программа дает сбой или просто нормально завершает работу (например, с return 0 из функции main). Сначала вам нужно уточнить, что вы подразумеваете под завершением, или, если вы сами не знаете, спросите своего учителя, что он или она имеет в виду под этим.   -  person Some programmer dude    schedule 11.01.2020
comment
На итерации после for (i=UINT_MAX; i>0; i++); i уменьшается по модулю UINT_MAX до нуля, и цикл завершается. Стандарт C11 — типы 6.2.5 (p9) ( второе предложение)   -  person David C. Rankin    schedule 11.01.2020
comment
Я удалил свой неверный ответ, в котором я написал, что поведение было неопределенным. Спасибо, что указали мне на это.   -  person Andreas Wenzel    schedule 11.01.2020
comment
@AndreasWenzel - вы можете отредактировать и просто исправить его и просто включить в него эту ссылку :)   -  person David C. Rankin    schedule 11.01.2020
comment
@DavidC.Rankin: я создал новый ответ. Мой старый ответ нельзя было спасти, и его пришлось полностью переписать, поскольку он был основан на ложной предпосылке. Я упомянул вас в разделе комментариев моего ответа за предоставление ссылки.   -  person Andreas Wenzel    schedule 11.01.2020


Ответы (2)


В принципе, вы правы во всем, что говорите. Как только счетчик цикла проходит мимо UINT_MAX (обычно 2 ^ 32-1), он возвращается к 0, что приводит к завершению цикла из-за того, что условие цикла больше не выполняется.

Единственное, что неправильно в том, что вы говорите, это то, что вы использовали слово «исключение». Нет ничего плохого в том, что результат целочисленной арифметической операции unsigned больше, чем UINT_MAX. В соответствии с Стандарт C11 — Типы 6.2.5 (p9) Результат очевиден. Он просто будет подвергнут по модулю UINT_MAX + 1, чтобы он соответствовал unsigned int.

Однако имейте в виду, что с знаковыми целыми числами переполнение вызывает неопределенное поведение . См. следующий вопрос StackOverflow для получения дополнительной информации:

Почему определено поведение целочисленного переполнения без знака, но переполнение целого числа со знаком не является?.

person Andreas Wenzel    schedule 11.01.2020
comment
Кредит принадлежит David C. Rankin за предоставление ссылки на соответствующий раздел стандарта C. Я просто взял это из его комментария (с его разрешения). - person Andreas Wenzel; 11.01.2020

Программа завершается, потому что счетчик i перейдет в 0, когда достигнет UINT_MAX.

person chmike    schedule 11.01.2020