在Linux中操作u64类型

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)

任何建议表示赞赏.非常感谢!

pax*_*blo 5

我怀疑,首先,你需要对那些大的'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++).