Должен ли я отключить предупреждение о несогласованности с помощью компилятора C?

Компилятор Microsoft C предупреждает, когда вы пытаетесь сравнить две переменные, а одна из них подписана, а другая - без знака. Например:

int a;    
unsigned b;

if ( a < b ) { // warning C4018: '&lt;' : signed/unsigned mismatch

}

Неужели это предупреждение в истории мира когда-либо попадалось в реальную ошибку? Почему это все равно?

Ответы

Ответ 1

О, это так. Но наоборот. Игнорирование этого предупреждения вызвало огромную головную боль для меня в один прекрасный день. Я писал функцию, которая построила график, и смешанные подписанные и неподписанные переменные. В одном месте я сравнивал отрицательное число с непознанным:

int32_t t; ...
uint32_t ut; ...

if(t < ut) { 
    ...
}

Угадайте, что случилось? Подписанный номер получил статус unsigned, и, следовательно, он был больше в конце, хотя первоначально он был ниже нуля. Мне понадобилось пару часов, пока я не нашел ошибку.

Ответ 2

Никогда не игнорируйте предупреждения компилятора.

Ответ 3

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

Я бы не отключил его - я не думаю, что всегда знаю лучше, чем компилятор (не в последнюю очередь потому, что я часто этого не делаю), и особенно потому, что иногда ошибаюсь при недосмотре, когда компилятор этого не делает.

Ответ 4

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

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

Ответ 5

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

например. -1 равен 4294967295 при преобразовании из подписанного в unsigned, теперь сравните это с 100 (без знака)

Ответ 6

Предупреждения существуют с определенной целью... Они заставляют вас думать о своем коде!

Лично я всегда указывал, если это возможно, подписанное → unsigned и unsigned → подписанное. Делая это, вы обеспечиваете, чтобы вы взяли на себя ответственность за транзакцию и знаете, что произойдет. Я понимаю, что это может быть не всегда возможно, в зависимости от проекта, чтобы сделать это, но всегда стремимся к 0 предупреждениям компилятора... это может только помочь!

Ответ 7

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

Если они вас раздражают, и вы принимаете/понимаете ситуацию, тогда установите бросок и двигайтесь дальше.

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

Ответ 8

Я даже сконфигурировал компилятор для предупреждения об ошибке компиляции. по причинам, о которых уже говорили другие парни.

Если я когда-либо сталкиваюсь с несоответствием подписанного/неподписанного, я спрашиваю себя, почему я выбрал другую "подпись". Обычно это ошибка дизайна.

Ответ 9

@gimel Объяснение о стрельбе по всей ноге найденной позади вашей ссылки действительно хорошо для этой проблемы.

- "Кто-то, кто избегает простых проблем, может просто возглавить не очень простой".

Это всегда верно, когда вы конвертируете между различными типами, и вы не проверяете те значения, которые могут навредить вам.

/Johan

Обновление: правильный способ конвертировать из uint в int - проверить значения против limits.h, или что-то в этом роде. (Но я редко делаю это сам, даже ты, я знаю, должен...:-)

Ответ 10

Я думаю, что лучше всего конвертировать ваш номер UNsigned в число, подписанное (до сравнения). Вместо того, чтобы наоборот.

Ответ 11

Просто один из многих способов, с помощью которых C позволяет снимать себя в ногу - вам лучше знать, что вы делает. Копия C приписывается Bjarne Stroustrup, создатель С++.