【发布时间】:2010-02-04 22:46:42
【问题描述】:
我正在尝试使用预处理器确定给定编译器的整数类型大小之间的关系。我的要求是我有两种类型,一种是无符号类型,一种是有符号类型,能够存储所述无符号类型可以存储的每个正数。即我必须确保我的ll_ssize 类型可以存储至少与ll_usize 可以存储一样多的正和负整数。
不幸的是,long long 和 long 和 int 的确切关系没有被 C 标准定义;在some machines(例如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 的转换不正确,因为我的编译器(Mac OS 10.6 X Snow Leopard 上的 clang)会发出以下警告:
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。浪费可以作为这些功能的论据;但是,对于存储在系统中的实际列表上的索引的浪费并不是。
【问题讨论】:
-
我没有提供任何解决方案,但我可以告诉您,使用大多数 C 预处理器执行 -2^64 会很困难。
-
我看起来不够仔细,无法给出答案,但是,在无符号数上使用一元 - 运算符是没有意义的。它是无符号的,它没有任何负值。编译器需要进行的转换才能保持其意义,这让它变得很糟糕。
-
是的,这就是我要解决的问题。我不能在预处理器中进行投射;因此我需要某种方法来使这个数学“合法”。显然,试图提供最大可用类型的负表示将是……#fail。
标签: c integer c-preprocessor primitive-types