C89: подписано/без подписного несоответствия

StackOverflow https://stackoverflow.com/questions/2262728

  •  20-09-2019
  •  | 
  •  

Вопрос

Подписаны/не значат несоответствия, обязательно плохими?

Вот моя программа:

int main(int argc, char *argv[]) {
    unsigned int i;

    for (i = 1; i < argc; i++) { // signed/unsigned mismatch here

    }
}

argc Подписано, i не является. Это проблема?

Это было полезно?

Решение

«Подписанные/беспигнированные несоответствия» могут быть плохими. В своем вопросе вы спрашиваете о сравнениях. При сравнении двух значений одного и того же базового типа, но одного подписанного и одного неподписанного, подписанное значение преобразуется в неподписание. Так,

int i = -1;
unsigned int j = 10;

if (i < j)
    printf("1\n");
else
    printf("2\n");

Отпечатки 2, а не 1. Это потому, что в i < j, i преобразуется в unsigned int. (unsigned int)-1 равно UINT_MAX, очень большое количество. Условие, таким образом, оценивается в ложь, и вы попадаете в else пункт.

Для вашего конкретного примера, argc Гарантированно будет неотрицательным, поэтому вам не нужно беспокоиться о «несоответствии».

Другие советы

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

Это не плохо. Я бы установил предупреждения компилятора, касающиеся подписанного/неподписанного несоответствия, потому что плохие вещи могут произойти, даже если они маловероятны или невозможно. Когда вам придется исправить ошибку из -за подписанного/неподписанного несоответствия, компилятор в основном говорит: «Я вам так сказал». Не игнорируйте предупреждение, которое там по какой -то причине.

Это только косвенно проблема.

Плохие вещи могут произойти, если вы используете подписанные целые числа для битовых операций, таких как &, |, << а также >>.
Совершенно разные плохие вещи могут произойти, если вы используете беспигнированные целые числа для арифметики (недостаточный поток, бесконечные петли при тестировании, если число >= 0 так далее.)

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

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

Иногда у вас нет выбора, например, при выполнении арифметики по значениям типа size_t в коде управления памятью.

В вашем примере я бы придерживался int, только потому, что проще иметь меньше типов и int все равно будет там, так как это тип первого аргумента main().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top