如何确定预处理器中 C 整数类型 MIN/MAX 的关系?

发布于 2024-08-20 03:55:00 字数 1915 浏览 3 评论 0原文

我试图使用预处理器确定给定编译器的整数类型大小的关系。我的要求是我有两种类型,其中一种是无符号的,另一种是有符号类型,能够存储所述无符号类型可以存储的每个正数。即我必须确保我的 ll_ssize 类型可以存储至少与 ll_usize 可以存储的正整数和负整数一样多。

不幸的是,long longlongint 的确切关系并未由 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏九 2024-08-27 03:55:00

-(LLONG_MIN+1) > 怎么样? (ULONG_MAX-1) ?

How about -(LLONG_MIN+1) > (ULONG_MAX-1) ?

不一样的天空 2024-08-27 03:55:00

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文