Как я могу определить отношение C целочисленного типа MIN / MAX в препроцессоре? - PullRequest
0 голосов
/ 05 февраля 2010

Я пытаюсь определить соотношение размеров целочисленных типов данного компилятора, используя препроцессор. Мое требование состоит в том, чтобы у меня было два типа, один из которых является беззнаковым, а другой - тип со знаком, способный хранить каждое положительное число, которое может хранить указанный тип без знака. то есть я должен убедиться, что мой тип 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. Трата приемлема в качестве аргументов этих функций; тем не менее, потери для индексов в фактических списках , хранящихся в системе, не являются.

Ответы [ 2 ]

4 голосов
/ 05 февраля 2010

Как насчет -(LLONG_MIN+1) > (ULONG_MAX-1)?

0 голосов
/ 05 февраля 2010

Как насчет ULONG_MAX < LLONG_MAX?

Забудьте, что «меньше или равно», вы хотите, чтобы оно было строго меньше .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...