Должен ли я отключить предупреждение о несогласованности с помощью компилятора C?
Компилятор Microsoft C предупреждает, когда вы пытаетесь сравнить две переменные, а одна из них подписана, а другая - без знака. Например:
int a;
unsigned b;
if ( a < b ) { // warning C4018: '<' : 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, создатель С++.