Может ли этот C-бросок избежать сравнения со знаком / без знака, какой-либо смысл? - PullRequest
3 голосов
/ 16 апреля 2010

Я рассматриваю проект C ++ и вижу следующее:

std::vector<SomeType> objects;

//then later
int size = (int)objects.size();
for( int i = 0; i < size; ++i ) {
    process( objects[i] );
}

Вот что я вижу. std::vector::size() возвращает size_t, который может иметь некоторый размер, не связанный с размером int. Даже если sizeof(int) == sizeof(size_t) int подписано и не может содержать все возможные значения size_t. Таким образом, приведенный выше код может обрабатывать только нижнюю часть очень длинного вектора и содержит ошибку. Правильный путь - использовать size_t как для переменной size, так и для индекса цикла.

Тем не менее, мне любопытно, почему автор мог написать это?

Мое единственное предположение, что сначала он пропустил приведение (int), а компилятор выдал что-то вроде Visual C ++ C4018 предупреждение:

warning C4018: '<' : signed/unsigned mismatch

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

Есть ли еще какие-то вменяемые причины для этого C-броска?

Ответы [ 4 ]

9 голосов
/ 16 апреля 2010

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

И ... возможно, в некоторых частях программы он фактически сравнивал «размер» с чем-то еще, что было интинтипированно, поэтому создание размера типом «size_t» исправило бы это в одном месте, но сломало бы это в другом месте.

9 голосов
/ 16 апреля 2010

Я бы сказал, что подавляющее использование C в C и C ++ заключается в том, чтобы просто заставить компилятор замолчать, без особых усилий или усилий, чтобы понять, о чем он говорит. Грустно, но верно.

4 голосов
/ 16 апреля 2010

Очевидным ответом будет использование:

size_t size = objects.size();
for( size_t i = 0; i < size; ++i ) {
    process( objects[i] );
}

или быть педантично правильным:

typedef std::vector<SomeType>::size_type s_t;
s_t size = objects.size();
for (s_t i=0; i<size; ++i)
    process(objects[i]);

OTOH, если вы не уверены, что вам нужно написать цикл самостоятельно, вам лучше использовать алгоритм:

std::foreach(objects.begin(), objects.end(), process);
0 голосов
/ 16 апреля 2010
unsigned int size = (int)objects.size();
for( unsigned int i = 0; i < size; ++i ) {
    process( objects[i] );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...