我试图在一个 long int
中存储 3 个整数(即每个 21 位)使用这些宏:
typedef long int Triple;
#define TR_A(o) ((int)((o & 0x7FFFFC0000000000) >> 42))
#define TR_B(o) ((int)((o & 0x000003FFFFE00000) >> 21))
#define TR_C(o) ((int)(o & 0x00000000001FFFFF))
#define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))
所以这个想法是
o
是 64 位,而 a
, b
, c
每个是 32 个。存放在内部时 o
它们是 21 位,64 位是空位,a
, b
,然后 c
.我收到一堆这些错误:
warning: left shift count >= width of type [-Wshift-count-overflow]
#define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))
^
是否可以向
TR_A
添加内容?/TR_B
/TR_C
指定 o
长?有没有更好的方法来做到这一点?
我希望能够将这些作为简单值而不是指针返回。在 PC 上使用 Linux。
最佳答案
您可以指定整数文字(常量)应解释为 long int
通过添加 L
后缀(或小写 l
- 但为了我的舒适,这看起来太像 1
)。同样,对于 long long int
,添加 LL
后缀。
对于您的宏,您还需要显式转换参数,a
, b
和 c
到适当的( long
或 long long
)类型。
但是,与其依赖特定的编译器来实现 long int
作为 64 位类型(许多编译器没有,并且 int
和 long int
都使用 32 位,并且需要 long long int
用于 64 位类型),您应该使用定义的位宽特定类型在 <stdint.h>
头文件。
因此,以下代码应该是无警告和可移植的:
#include <stdint.h>
typedef int64_t Triple;
#define TR_A(o) ((int32_t)(((int64_t)(o) & 0x7FFFFC0000000000LL) >> 42))
#define TR_B(o) ((int32_t)(((int64_t)(o) & 0x000003FFFFE00000LL) >> 21))
#define TR_C(o) ((int32_t)((int64_t)(o) & 0x00000000001FFFFFLL))
// EDIT/NOTE: I have changed the bitwise & operations to | in the macro below,
// as this is probably what you actually want (otherwise it will give 0 always)!
#define MK_TR(a,b,c) ((int64_t)(((int64_t)(a) << 42) | ((int64_t)(b) << 21) | (int64_t)(c)))
此外,始终将宏参数包含在括号中是非常好的做法(例如上面最后一行中的
(c)
)。如果没有这个,使用表达式作为参数调用宏可能会给您带来意想不到的结果,这可能很难追踪。这将是一个恰当的例子:int a = 1, b = 2, c = 3;
Triple test = MK_TR(a + 1, b + 1, c + 1); // Unexpected(?) result.
关于c - 在宏(或其他东西)中指定 int 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61875304/