Подтвердить что ты не робот

Предупреждение size_t против int

Я всегда предупреждаю о следующем типе кода.

std::vector v;
for ( int i = 0; i < v.size(); i++) {
}

warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data

Я понимаю, что size() возвращает size_t, просто хотел знать, насколько безопасно игнорировать это предупреждение или я должен сделать всю свою переменную цикла типа size_t

4b9b3361

Ответ 1

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

Еще лучше, используйте итераторы:

for( auto it = v.begin(); it != v.end(); ++it )

(Если ваш компилятор не поддерживает С++ 11, используйте std::vector<whatever>::iterator вместо auto)

С++ 11 также упрощает выбор наилучшего типа индекса (в случае, если вы используете индекс в некоторых вычислениях, а не только для подписи v):

for( decltype(v.size()) i = 0; i < v.size(); ++i )

Ответ 2

Что такое size_t?
size_t соответствует интегральному типу данных, возвращаемому оператором языка sizeof и определяется в файле заголовка (среди прочих) как unsigned integral type.

Можно ли отбрасывать size_t до int?
Вы можете использовать бросок, если вы уверены, что размер никогда не будет > чем INT_MAX.

Если вы пытаетесь написать переносимый код, он безопасен не, потому что

size_t в 64 bit Unix есть 64 bits
size_t в 64 bit Windows есть 32 bits

Итак, если вы портируете код из Unix в WIndows, а если выше, то вы потеряете данные.

Рекомендуемый ответ

Учитывая оговорку, нужно сделать i of unsigned integral type или даже лучше использовать его как тип size_t.

Ответ 3

безопасно ли игнорировать это предупреждение или я должен сделать всю свою переменную цикла типа size_t

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

Технически, std::vector::size возвращает std::vector::size_type.

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

Ответ 4

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

поскольку size() возвращает a size_t (not int), тогда это должен быть тип данных, с которым вы сравниваете его.

std::vector v;
for ( size_t i = 0; i < v.size(); i++) {
}

Ответ 5

Здесь альтернативный вид Бьярне Страуструпа: http://www.stroustrup.com/bs_faq2.html#simple-program

for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

Да, я знаю, что могу объявить, что я должен быть vector:: size_type а не простой int для спокойных предупреждений от некоторых подозрительных компиляторов, но в этом случае я считаю, что слишком педантичный и отвлекает внимание.

Это компромисс. Если вы обеспокоены тем, что v.size() может пройти выше 2,147,483,647, используйте size_t. Если вы используете я внутри своего цикла больше, чем просто смотрите внутри вектора, и вас беспокоят тонкие связанные или неподписанные ошибки, используйте int. По моему опыту, последний вопрос более распространен, чем первый. Ваш опыт может отличаться.

Также см. Почему size_t unsigned?.