2017-02-21 5 views
0

Здесь есть цикл, который проходит через строку C обратной:Сравнивая беззнаковое выражение с 0

size_t slen = strlen(string); 
for (size_t i = slen-1; i >= 0; i--) { 
    /* do stuff */ 
} 

И когда я скомпилировать этот код с gcc -Wall -Wextra -std=c99 -o code code.c, я получаю это предупреждение:

предупреждение: сравнение of unsigned expression> = 0 всегда верно [-Wtype-limits]

При обращении к этому предупреждению я заменил этот цикл вместо:

for (int i = (int)slen-1; i >= 0; i--) { 

Это прекрасно работает, но мне было интересно узнать, был ли это способ сделать первый цикл все еще скомпилированным без предупреждения выше? Это предупреждение срабатывает только при компиляции с -Wextra.

+3

Почему вы хотите сделать первый цикл компиляции без предупреждений? Это логически неверно, как предупреждает вам предупреждение. Поэтому не уверен, чего вы пытаетесь достичь, пытаясь сохранить этот неправильный код. – kaylum

+0

@kaylum просто интересно из любопытства. Прочитав немного больше, я должен согласиться с вами, что это неправильный код. – RoadRunner

+1

В чем смысл компиляции первого цикла? Необязательная переменная всегда '> = 0', поэтому зачем даже проверять? –

ответ

2

Целочисленное целое число никогда не может быть меньше 0. Вот что означает «без знака». Таким образом, ваша петля никогда не закончится.

Вместо этого вы можете использовать:

for (size_t i = slen; i-- > 0;) { 

Это выполняет проверку перед декремента i, поэтому последняя итерация цикла будет происходить с i == 0, а затем тест i-- > 0 выходит из строя, нарушение цикла.

Related thread.

+0

Cheers @ M.M, ваше объяснение имеет смысл :) – RoadRunner

2

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

for (size_t i = 0, e = strlen(string); i != e; ++i) { 
    const size_t ri = e - i - 1; 

    /* do stuff with index ri */ 
} 

Эта конструкция делает − 1-смещение для отношения итератора-к-Reverse-итератора очевидным, что позволяет избежать каких-либо проблем, знаковости, и дает вам круглый счетчик бесплатно.

+0

Да, я думаю, я больше не смотрел, как это было написано. Спасибо за объяснение, хотя это очень полезно :). – RoadRunner