Некоторое время назад я опубликовал короткую заметку о подобных проблемах в своем блоге, и короткий ответ:
Всегда используйте правильные целочисленные типы C ++
Длинный ответ:
При программировании на C ++ рекомендуется использовать правильные целочисленные типы, соответствующие конкретному контексту. Немного строгости всегда окупается. Нередко наблюдается тенденция игнорировать целочисленные типы, определенные как специфичные для стандартных контейнеров, а именно size_type. Он доступен для номера стандартного контейнера, такого как std :: string или std :: vector. Такое невежество может легко отомстить.
Ниже приведен простой пример неверно используемого типа для получения результата функции std :: string :: find. Я совершенно уверен, что многие ожидают, что здесь нет ничего плохого в неподписанном int. Но на самом деле это просто ошибка. Я запускаю Linux на 64-битной архитектуре, и когда я компилирую эту программу как есть, она работает как положено. Однако, когда я заменяю строку в строке 1 на abc, она все равно работает, но не так, как ожидалось: -)
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "a:b:c"; // "abc" [1]
char delim = ':';
unsigned int pos = s.find(delim);
if(string::npos != pos)
{
cout << delim << " found in " << s << endl;
}
}
Исправить очень просто. Просто замените unsigned int на std :: string :: size_type. Эту проблему можно избежать, если кто-то, кто написал эту программу, позаботится об использовании правильного типа. Не говоря уже о том, что программа будет переносимой сразу.
Я сталкивался с подобными проблемами довольно много раз, особенно в коде, написанном бывшими программистами C, которые не любят носить дуло строгости, которую требует система типов C ++. Приведенный выше пример является тривиальным, но я считаю, что он хорошо представляет корень проблемы.
Я рекомендую блестящую статью 64-битная разработка , написанную Андреем Карповым, где вы можете найти гораздо больше по теме.