有没有办法在编译时计算整数类型的宽度? [英] Is there any way to compute the width of an integer type at compile-time?

查看:29
本文介绍了有没有办法在编译时计算整数类型的宽度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

char/bytes 为单位的整数类型(或任何类型)的大小很容易计算为sizeof(type).一个常见的习惯用法是乘以 CHAR_BIT 以找到该类型占用的位数,但在使用填充位的实现中,这将不等于值中的 width位.更糟糕的是,代码如下:

x>>CHAR_BIT*sizeof(type)-1

如果 CHAR_BIT*sizeof(type) 大于 type 的实际宽度,则实际上可能有未定义的行为.

为简单起见,我们假设我们的类型是无符号的.那么type的宽度就是ceil(log2((type)-1).有没有办法把这个值计算成常量表达式?

解决方案

有一个类似函数的宏可以判断整数类型的值位,但是仅当您已经知道该类型的最大值时.您是否会获得编译时常量取决于您的编译器,但我猜在大多数情况下答案是肯定的.

感谢 Hallvard B. Furuseth 在回复 comp.lang.c 上的问题

/* inttype_MAX 或任何 (1<

<块引用>

IMAX_BITS(INT_MAX) 计算 int 中的位数,而 IMAX_BITS((unsigned_type)-1) 计算 unsigned_type 中的位数.无论如何,直到有人实现 4 GB 整数:-)


感谢 Eric Sosman 这个 [替代版本](http://groups.google.com/group/comp.lang.c/msg/e998153ef07ff04b?dmode=source) 应该可以使用 less超过 2040 位:**(编辑 2011 年 1 月 3 日晚上 11:30 EST:原来这个版本也是由 Hallvard B. Furuseth 编写的)**

/* inttype_MAX 或任何 (1<


**请记住,尽管无符号整数类型的宽度等于值位数,但有符号整数类型的宽度要大一(第 6.2.6.2/6 节).** 这在我的文章中特别重要对您的问题的原始评论我错误地指出 IMAX_BITS() 宏在实际计算值位数时计算宽度.对于那个很抱歉!

因此,例如 IMAX_BITS(INT64_MAX) 将创建一个 63 的编译时常量.但是,在此示例中,我们处理的是有符号类型,因此您必须添加 1 来说明符号如果你想要一个 int64_t 的实际宽度,当然是 64.

在一个单独的 comp.lang.c 讨论中,名为 blargg 的用户详细介绍了宏的工作原理:
Re: 使用预处理器计算位整数类型...

请注意,宏仅适用于 2^n-1 个值(即二进制中的所有 1),正如任何 MAX 值所预期的那样.另请注意,虽然很容易获得无符号整数类型 (IMAX_BITS((unsigned type)-1)) 的最大值的编译时常数,但在撰写本文时,我没有'不知道有什么方法可以在不调用实现定义的行为的情况下对有符号整数类型做同样的事情.如果我发现我会在这里回答我自己的相关 SO 问题:
C 问题:off_t(和其他有符号整数类型)最小值和最大值 - Thinbug

The size of an integer type (or any type) in units of char/bytes is easily computed as sizeof(type). A common idiom is to multiply by CHAR_BIT to find the number of bits occupied by the type, but on implementations with padding bits, this will not be equal to the width in value bits. Worse yet, code like:

x>>CHAR_BIT*sizeof(type)-1

may actually have undefined behavior if CHAR_BIT*sizeof(type) is greater than the actual width of type.

For simplicity, let's assume our types are unsigned. Then the width of type is ceil(log2((type)-1). Is there any way to compute this value as a constant expression?

解决方案

There is a function-like macro that can determine the value bits of an integer type, but only if you already know that type's maximum value. Whether or not you'll get a compile-time constant depends on your compiler but I would guess in most cases the answer is yes.

Credit to Hallvard B. Furuseth for his IMAX_BITS() function-like macro that he posted in reply to a question on comp.lang.c

/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 
                  + (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))

IMAX_BITS(INT_MAX) computes the number of bits in an int, and IMAX_BITS((unsigned_type)-1) computes the number of bits in an unsigned_type. Until someone implements 4-gigabyte integers, anyway:-)


And credit to Eric Sosman for this [alternate version](http://groups.google.com/group/comp.lang.c/msg/e998153ef07ff04b?dmode=source) that should work with less than 2040 bits: **(EDIT 1/3/2011 11:30PM EST: It turns out this version was also written by Hallvard B. Furuseth)**

/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))


**Remember that although the width of an unsigned integer type is equal to the number of value bits, the width of a signed integer type is one greater (§6.2.6.2/6).** This is of special importance as in my original comment to your question I had incorrectly stated that the IMAX_BITS() macro calculates the width when it actually calculates the number of value bits. Sorry about that!

So for example IMAX_BITS(INT64_MAX) will create a compile-time constant of 63. However, in this example, we are dealing with a signed type so you must add 1 to account for the sign bit if you want the actual width of an int64_t, which is of course 64.

In a separate comp.lang.c discussion a user named blargg gives a breakdown of how the macro works:
Re: using pre-processor to count bits in integer types...

Note that the macro only works with 2^n-1 values (ie all 1s in binary), as would be expected with any MAX value. Also note that while it is easy to get a compile-time constant for the maximum value of an unsigned integer type (IMAX_BITS((unsigned type)-1)), at the time of this writing I don't know any way to do the same thing for a signed integer type without invoking implementation-defined behavior. If I ever find out I'll answer my own related SO question, here:
C question: off_t (and other signed integer types) minimum and maximum values - Stack Overflow

这篇关于有没有办法在编译时计算整数类型的宽度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆