Вопрос

Предположим, у меня есть этот (C ++ или, возможно, C) код:

vector<int> my_vector;
for (int i = 0; i < my_vector.size(); i++) {
    my_vector[i] = 0;
}

Мне все равно, правильно ли все сделано.Важная часть содержится в объявлении цикла for.Компилятор выдает несоответствие signed / unsigned для этого, поскольку size() возвращает unsigned int, а не signed .Насколько важно измениться i в неподписанный?Я по привычке объявляю счетчики циклов целыми числами, но если это потенциальная ошибка, я заставлю себя избавиться от этой привычки.

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

Решение

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

В данном случае, для этой конкретной ошибки, это, вероятно, не имеет большого значения - на 32-разрядной платформе у вас должно быть более 2 миллиардов записей в векторе, прежде чем unsigned превратится в отрицательное значение со знаком.Получение такого вектора исчерпало бы всю вашу память, поэтому, вероятно, невозможно перейти в состояние, в котором несоответствие signed / unsigned имело бы значение.

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

Технически, i должно быть vector<int>::size_type.У вас должно войти в привычку использовать typedefs в вашем коде:

typedef vector<int> VectorType;
VectorType my_vector;
for (VectorType::size_type i = 0; i < my_vector.size(); i++) {
    my_vector[i] = 0;
}

Теперь, если мы изменим его на deque, мы меняем только одну строку.Даже если это какой-то пользовательский контейнер с дурацким size_type, у вас возникает теплое, нечеткое ощущение, что все будет в порядке.А это дорогого стоит.Даже при использовании простого unsigned / подписанного, есть некоторые сложные проблемы с продвижением при использовании подписанного / неподписанного преобразования, которые неизбежно вернутся к вам.

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

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

11111111 < 10000000

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

убедитесь, что предупреждений как можно меньше.

Как было сказано выше, используйте vector::size_type;или используйте итератор для перебора вашего вектора.Убедитесь, что все ваши собственные предупреждения обрабатываются как ошибки.

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