Подтвердить что ты не робот

Каково объяснение "предупреждения: считая, что цикл не бесконечен"

Я только принял решение изменить столько переменных от unsigned до int и после перекомпиляции рассматриваемого кода было встречено этим предупреждающим сообщением:

freespace_state.c:203: warning: assuming that the loop is not infinite

Соответствующая строка:

for (x = startx; x <= endx; ++x, ++xptr)

Этот цикл состоит из 60 строк кода (включая пробел/скобки и т.д.) и имеет goto внутри него и по крайней мере одно вхождение continue.

В этом случае я считаю, что я благодарен GCC за то, что этот цикл не бесконечен, потому что он никогда не должен зацикливаться бесконечно.

Что GCC пытается рассказать мне здесь?

Грамматика предупреждения почти наводит на мысль, что предупреждение должно быть принято в контексте какого-либо другого предупреждения, но в этом контексте нет.

[править] Это полностью моя вина. Я украл некоторые варианты оптимизации и предупреждения из вопроса здесь, где-то, не понимая их, и с тех пор забыл о них.

См. ответ Марка Рушакова, и, кроме того, я также использовал -Wunsafe-loop-optimizations для явного предупреждения, если GCC делает предположения о цикле. См. http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

4b9b3361

Ответ 1

Согласно этот патч GCC с 2005 года, похоже, что GCC выполняет "небезопасную оптимизацию цикла" (и вы предупреждаетесь, потому что -funsafe-loop-optimizations). Если цикл бесконечен, эта определенная оптимизация как-то сработает.

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

Другая важная часть патча:

@opindex Wunsafe-loop-optimizations
Warn if the loop cannot be optimized because the compiler could not
assume anything on the bounds of the loop indices.  With
@option{-funsafe-loop-optimizations} warn if the compiler made
+such assumptions.

Ответ 2

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

Ответ 3

Причина, по которой GCC предупреждает вас, заключается в том, что она вытащила небезопасную оптимизацию. Вместо

for (x = startx; x <= endx; ++x, ++xptr)

он в основном использует:

for( x = startx; x < (endx+1); ++x, ++xptr)

что верно, только если endx+1 не переполняется, но это происходит, когда endx является самым большим возможным значением, что означает, что x <= endx всегда истинно. Компилятор предполагает, что этого не происходит.

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

Одним из примеров является пример, когда, например, x и endx являются целыми числами, оптимизация может быть фактически интерпретирована как разрешенная стандартом, если endx==MAX_INT у вас будет условие, являющееся истинным, что приведет к тому, что x в конечном итоге переполняет поведение undefined, это означает, что компилятор может предположить, что этого не происходит. Пропуск цикла полностью соответствует стандарту соответствия в соответствии с этими интерпретациями.

Другим случаем является то, что программа не завершается во время цикла или не изменяет изменчивую память (т.е. имеет наблюдаемое поведение), что означает, что бесконечный цикл означает поведение undefined (IIRC, по крайней мере, компилятору разрешено предположить, что это не происходит).