Неопределенное поведение в цикле for - разве разделение выражений не должно сделать это четко определенным?

Я знаю, что эта тема была немного избита до смерти на SO, но я все еще немного смущен ситуацией, показанной ниже, и несколько человек, похоже, согласились, что это было правильно.

Я понимаю, что вы не можете изменить/использовать измененную переменную более одного раза без промежуточной точки последовательности, если это не будет неопределенным поведением. Я думал, что внутри цикла for все i != 0;, i < n; и i-- были отдельными выражениями, оцениваемыми в известное время и разделенными точками последовательности (поскольку они являются полными выражениями).

Почему это может привести к неопределенному поведению?

Изображение форума

взято с форума: http://www.frihost.com/forums/vt-48979.html


person John Humphreys    schedule 15.02.2012    source источник
comment
for (i != 0; не имеет никакого смысла. Вы проверяете, не равно ли i нулю, а затем выбрасываете результат. Почему вы хотите это сделать?   -  person fredoverflow    schedule 16.02.2012
comment
Я не знаю, это не мой код :p. Меня просто интересовало, что сделало его неопределенным, и я думаю, что это проблема подписания/неподписания.   -  person John Humphreys    schedule 16.02.2012


Ответы (3)


Для исходного кода сообщения

for (i = 0; i < n; i--)

код не определен из-за того, как работает целочисленная арифметика со знаком. Нет никакой гарантии, что i когда-нибудь завершится и станет положительным. При арифметике без знака код становится определенным (но поведение не указано, поскольку размер unsigned int не указан).

Что касается строки, соответствующей вашему снимку экрана, переменная i никогда не инициализируется, отсюда и неопределенное поведение.

person Alexandre C.    schedule 15.02.2012
comment
Ах, я думаю, я слишком сосредоточился на этой линии и подумал, что это что-то более тонкое, ха-ха. Спасибо. - person John Humphreys; 16.02.2012

for (i = 0; i < n; i--)

Это поведение неопределенного кода, если i является целым числом со знаком, И если выражение i-- приводит к переполнению i. (На самом деле в терминологии C могут переполняться только целые числа со знаком.)

person ouah    schedule 15.02.2012
comment
Можете ли вы объяснить, почему декремент постфикса для целого числа приводит к его переполнению? - person Allan Ruin; 27.05.2012

Другие ответы прокомментировали код, отличный от того, который был опубликован на самом деле. Код изначально был головоломкой, и одним из предложенных решений было написать следующее:

for (i != 0; i < n; i--)

Проблема в том, что он никогда не присваивает начальное значение i. Обычно это входит в первую часть конструкции for, но здесь она была переписана в (совершенно бессмысленную) i != 0. (Это бессмысленно, поскольку у него нет побочных эффектов, и его значение не используется — но, эй, это была головоломка.)

Следовательно, это может запускать цикл произвольное количество раз.

person Lindydancer    schedule 15.02.2012