如何确定预处理器中 C 整数类型 MIN/MAX 的关系?
我试图使用预处理器确定给定编译器的整数类型大小的关系。我的要求是我有两种类型,其中一种是无符号的,另一种是有符号类型,能够存储所述无符号类型可以存储的每个正数。即我必须确保我的 ll_ssize
类型可以存储至少与 ll_usize
可以存储的正整数和负整数一样多。
不幸的是,long long
与 long
和 int
的确切关系并未由 C 标准定义;在某些机器(例如LP64机器)上,< code>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 。浪费可以作为这些函数的参数;然而,系统中存储的实际列表上的索引却没有浪费。
I’m trying to determine the relationship of a given compiler’s integer types’ sizes using the preprocessor. My requirement is that I have two types, one of which is unsigned, and one of which is a signed type capable of storing every positive number that said unsigned type can store. i.e. I have to ensure that my ll_ssize
type can store at least as many positive and negative integers as the ll_usize
can store.
Unfortunately, the exact relationships of long long
and long
and int
aren’t defined by the C standards; on some machines (such as LP64 machines), the data storage of a long
is going to be exactly equivalent to a long long
.
Thus, I have to use the preprocessor to attempt to determine the largest possible type that also has a single larger type available; the unsigned version of that type becomes ll_usize
, and the signed version of the larger type becomes ll_ssize
.
Here is the code I’m using now:
#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
Now, on to my problem. I can’t preform casts in preprocessor expressions, but it seems that ULONG_MAX
is being incorrectly converted, as my compiler (clang
on Mac OS 10.6 X Snow Leopard) spits out the following warning:
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
~~~~~~~~~ ^ ~~~~~~~~~~~~
Does anybody know of a way for me to work around this conversion error? Or, preferably, a better solution to the overall problem, because I really dislike these ugly preprocessor expressions.
Edit: I should also point out why I’m doing this, instead of just using the largest signed type available: I don’t want to waste the memory space for all of those negative integers, when I’m never going to be storing negative numbers. Specifically, the unsigned type (ll_usize
) is used for the stored indexes into a linked list; however, some functions that operate on the linked list can take negative index arguments, and work from the opposite end of the linked list: those functions are declared to take ll_ssize
instead. The waste is acceptable as the arguments to those functions; however, the waste for the indexes on the actual lists stored in the system is not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
-(LLONG_MIN+1) > 怎么样? (ULONG_MAX-1) ?
How about
-(LLONG_MIN+1) > (ULONG_MAX-1)
?ULONG_MAX < 怎么样? LLONG_MAX?
忘记“小于或等于”的东西,您希望它严格小于。
How about
ULONG_MAX < LLONG_MAX
?Forget that "less-than-or-equal" stuff, you want it to be strictly less than.