Die*_*yen 2 c unix linux 64-bit
我们如何在Linux内核中操作u64类型的32位高位和32位低位.我试过这个,但编译器报告了很多警告.
#define HI_BYTES(_a) (_a & 0xffffffff00000000)
#define LO_BYTES(_a) (_a & 0x00000000ffffffff)
/* _v is 32 bit value */
#define HI_BYTES_SET(_a, _v) do {_a = (_a & 0x00000000ffffffff) | (_v << 32)} while (0)
#define LO_BYTES_SET(_a, _v) do {_a = (_a & 0xffffffff00000000) | (_v)} while (0)
Run Code Online (Sandbox Code Playgroud)
任何建议表示赞赏.非常感谢!
我怀疑,首先,你需要对那些大的'ohkin'数字进行限定,这类似于:
0xffffffff00000000ULL
Run Code Online (Sandbox Code Playgroud)
简单的整数常量属于int类型,并且可能不足以容纳给定的值.
除此之外,你应该发布你得到的警告,这样我们就不必玩精神调试游戏了:-)
另一件可能有问题的是v << 3232位v.我可能会选择以下内容:
#define HI_BYTES(_a) (_a & 0xffffffff00000000ULL)
#define LO_BYTES(_a) (_a & 0x00000000ffffffffULL)
#define HI_BYTES_SET(_a, _v)\
do {\
u64 _xyzzy = _v;\
_a = (_xyzzy << 32) | LO_BYTES(_a)\
} while (0)
#define LO_BYTES_SET(_a, _v)\
do {\
u64 _xyzzy = _v;\
_a = HI_BYTES(_a) | (_xyzzy)\
} while (0)
Run Code Online (Sandbox Code Playgroud)
在进行任何位移之前,这将确保一切都是正确的类型.请记住,未经测试,您必须确认正确的行为.
但是,当然,我错过了尼古拉斯奈特在评论中提出的最明显的解决方案.完全摆脱宏.这可以通过函数更好地处理(如果你愿意,可以标记为内联,但我很少发现这是必要的,因为gcc无论如何都能非常好地优化事物).
这样,编译器可以强制数据类型和你没有遇到你总是做类似宏的问题#define SQR(x) ((x)*(x))和i = SQR(j++).