2013-03-26 2 views
6

Библиотека, над которой я работаю, должна использоваться как на 32, так и на 64-битных машинах; У меня много предупреждений компилятора, потому что на 64-битных машинах unsigned int != size_t.Что является недостатком замены size_t unsigned long

Есть ли недостаток в замене всех unsigned int s и size_t s на 'unsigned long'? Я ценю, что это выглядит не очень элегантно, но, во всяком случае, память не слишком большая проблема ... Мне интересно, есть ли вероятность каких-либо ошибок/нежелательного поведения и т. Д., Созданная такой операцией replace all (может вы приводите примеры)? Благодарю.

+0

Если в какой-то момент спецификации библиотек меняются, а 'size_t' будет подписан, у вас будет много проблем. – Spook

+0

Какова вероятность этого? size_t должен представлять адрес памяти ... –

+4

Единственным недостатком является то, что в 64-битной Windows 'size_t'' 'unsigned long long', потому что' long' составляет всего 32 бита (даже в 64-битном режиме). –

ответ

8

Какие предупреждения? Наиболее очевидным я могу подумать о «сужающемся преобразовании», то есть вы назначаете size_t на номер unsigned int и получаете предупреждение о том, что информация может быть потеряна.

Основной недостаток замены size_t с unsigned long что unsigned long не гарантируются быть достаточно большим, чтобы вместить все возможные значения size_t, и на Windows 64 он не является достаточно большим. Поэтому вы можете обнаружить, что у вас все еще есть предупреждения.

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

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

Оба типа (size_t и unsigned int) имеют действительные пользы, так что любой подход, который без разбора заменяет все их использование какого-либо другого типом должен быть неправильно :-) На самом деле, вы могли бы заменить все с size_t или uintmax_t и для большинство программ, которые были бы в порядке. Исключения составляют код, в котором используется код без знака того же размера, что и int, или что-то еще такое, что более крупный тип нарушает код.

4

Если вы используете size_t в тех местах, где вы должны получить size_t и заменить его unsigned long, вы будете вводить новые предупреждения.

пример:

size_t count = some_vector.size(); 

Заменить size_t с unsigned long, и (в той степени, они разные) вы ввели новое предупреждение (потому что some_vector.size() возвращает size_t - на самом деле std:::vector<something>::size_type, но на практике она должна оценить в то же самое).

+0

Я мог бы получить больше предупреждений, правда, но может ли повышаться вызвать настоящую проблему (например, ошибка)? –

+3

@YuccaV В любой программе, которая воспринимает себя всерьез, предупреждения являются настоящей проблемой. – Angew

+0

Это зависит от вашего кода. Если у вас есть - для другого примера - рассчитанные различия смещений и сравнение их для того, чтобы быть меньше нуля, с unsigned вы можете получить отрицания, отличные от unsigned, которые должны появиться где-то рядом с максимальным диапазоном, которое может представлять значение без знака этого типа (0x11111111 или аналогичный). Это зависит от вашей базы кода в основном. Точка Ангела действительна, хотя: лучше всего установить, чтобы ваш компилятор имел нулевое значение для предупреждений (для gcc это опция '-Werror'). – utnapistim

4

Стандарт не дает никаких гарантий относительно размеров таких типов, как int и long. size_t гарантированно будет достаточно большим, чтобы держать любой объект, а все контейнеры std работают на size_t.

Возможно, для платформы можно определить long размером менее size_t или иметь размер long, например, для параметров компиляции. Чтобы быть в безопасности, лучше придерживаться size_t.

Другой критерий, который следует учитывать, заключается в том, что size_t несет значение - «эта вещь используется для хранения размера или индекса». Это делает код немного более самодокументированным.

Смежные вопросы