Я пытаюсь определить соотношение размеров целочисленных типов данного компилятора, используя препроцессор. Мое требование состоит в том, чтобы у меня было два типа, один из которых является беззнаковым, а другой - тип со знаком, способный хранить каждое положительное число, которое может хранить указанный тип без знака. то есть я должен убедиться, что мой тип ll_ssize
может хранить как минимум столько положительных и отрицательных целых чисел, сколько может хранить ll_usize
.
К сожалению, точные отношения long long
и long
и int
не определены стандартами C; на некоторых машинах (таких как машины LP64) хранение данных long
будет в точности эквивалентно long long
.
Таким образом, я должен использовать препроцессор, чтобы попытаться определить максимально возможный тип, который также имеет единственный доступный тип больше ; версия без знака этого типа становится ll_usize
, а версия большего размера со знаком становится ll_ssize
.
Вот код, который я сейчас использую:
#if defined(ULONG_MAX) && defined(LLONG_MIN) && defined(LLONG_MAX) && \
LLONG_MIN <= -(ULONG_MAX) && ULONG_MAX <= LLONG_MAX
typedef unsigned long int ll_usize;
typedef signed long long int ll_ssize;
#elif defined(UINT_MAX) && defined(LONG_MIN) && defined(LONG_MAX) && \
LONG_MIN <= -(UINT_MAX) && UINT_MAX <= LONG_MAX
typedef unsigned int ll_usize;
typedef signed long int ll_ssize;
#else
typedef signed int ll_usize;
typedef signed int ll_ssize;
#endif
Теперь перейдем к моей проблеме. Я не могу предварительно преобразовать выражения в выражения препроцессора, но похоже, что ULONG_MAX
преобразовывается неправильно, так как мой компилятор (clang
в Mac OS 10.6 X Snow Leopard) выдает следующее предупреждение:
Source/Paws.o/Core/ll.h:21:15: warning: left side of operator converted from
negative value to unsigned: -9223372036854775808 to 9223372036854775808
LLONG_MIN <= -(ULONG_MAX) && ULONG_MAX <= LLONG_MAX
~~~~~~~~~ ^ ~~~~~~~~~~~~
Кто-нибудь знает, как мне обойти эту ошибку преобразования? Или, желательно, лучшее решение всей проблемы, потому что мне действительно не нравятся эти уродливые выражения препроцессора.
Редактировать: Я должен также указать, почему я делаю это, вместо того, чтобы просто использовать самый большой доступный тип со знаком: я не хочу тратить пространство памяти для всех этих отрицательных целых чисел, когда я никогда не буду хранить отрицательные числа. В частности, тип без знака (ll_usize
) используется для сохраненных индексов в связанном списке; однако некоторые функции, работающие со связанным списком, могут принимать отрицательные аргументы индекса и работать с противоположного конца связанного списка: эти функции объявлены для взятия ll_ssize
. Трата приемлема в качестве аргументов этих функций; тем не менее, потери для индексов в фактических списках , хранящихся в системе, не являются.