Предупреждения компилятора - PullRequest
3 голосов
/ 29 июня 2009

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

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

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

Ответы [ 6 ]

13 голосов
/ 29 июня 2009

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

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, вы получите теплое, нечеткое чувство, что все будет хорошо. И это многого стоит. Даже при использовании только неподписанного / подписанного, есть некоторые хитрые проблемы продвижения с использованием подписанного / неподписанного преобразования, которые неизбежно вернутся, чтобы укусить вас.

10 голосов
/ 29 июня 2009

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

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

6 голосов
/ 29 июня 2009

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

1 голос
/ 29 июня 2009

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

11111111 <10000000 </p>

0 голосов
/ 30 июня 2009

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

0 голосов
/ 29 июня 2009

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

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

...