我有以下功能:
void func(unsigned long v)
{
char max_byte = 0xFF;
char buffer[8];
buffer[0] = static_cast<char>((v) & max_byte);
buffer[1] = static_cast<char>((v >> 8) & max_byte);
buffer[2] = static_cast<char>((v >> 16) & max_byte);
buffer[3] = static_cast<char>((v >> 24) & max_byte);
buffer[4] = static_cast<char>((v >> 32) & max_byte);
buffer[5] = static_cast<char>((v >> 40) & max_byte);
buffer[6] = static_cast<char>((v >> 48) & max_byte);
buffer[7] = static_cast<char>((v >> 56) & max_byte);
}
采用unsigned long
参数并将其8个字节插入char
缓冲区(不要试图找出原因。它是一个有意义函数的简洁版本。)
此代码在64位上编译良好,但在32位上我得到以下警告:
warning: right shift count >= width of type
指的是行:
buffer[4] = static_cast<char>((v >> 32) & max_byte);
buffer[5] = static_cast<char>((v >> 40) & max_byte);
buffer[6] = static_cast<char>((v >> 48) & max_byte);
buffer[7] = static_cast<char>((v >> 56) & max_byte);
我想我理解这个警告,但我不知道我该怎么办才能在32位上顺利编译它。
答案 0 :(得分:8)
使用fixed-width integer types。在这种情况下,您需要std::uint64_t
。
答案 1 :(得分:5)
unsigned long
仅保证有32位。见here。您需要使用unsigned long long
来保证64位。
更好的方法是使用fixed width integer,即uint64_t
。它们在标题<cstdint>
(或<stdint.h>
)中定义。
答案 2 :(得分:2)
编写依赖于整数大小的代码时,您确实需要使用<stdint.h>
。
#include <stdint.h>
void func(uint64_t v)
{
static const uint8_t max_byte = 0xFF; // Let the compiler hardcode this constant.
uint8_t buffer[8];
buffer[0] = static_cast<uint8_t>((v) & max_byte);
buffer[1] = static_cast<uint8_t>((v >> 8) & max_byte);
buffer[2] = static_cast<uint8_t>((v >> 16) & max_byte);
buffer[3] = static_cast<uint8_t>((v >> 24) & max_byte);
buffer[4] = static_cast<uint8_t>((v >> 32) & max_byte);
buffer[5] = static_cast<uint8_t>((v >> 40) & max_byte);
buffer[6] = static_cast<uint8_t>((v >> 48) & max_byte);
buffer[7] = static_cast<uint8_t>((v >> 56) & max_byte);
}
答案 3 :(得分:0)
我可能错误地认为没有一个答案真正达到了这个问题的重点,因此这里就是这样。
编译为64位二进制文件时,long定义为64位值(或8字节),而32位二进制文件a long与32位或4位字节的int相同。
该问题有几种解决方案:
1.将参数重新定义为long long或int64,如其他响应中所建议的那样
2.添加预处理器定义以阻止违规位操作。如...
#ifdef __LP64__
buffer[4] = static_cast<uint8_t>((v >> 32) & max_byte);
buffer[5] = static_cast<uint8_t>((v >> 40) & max_byte);
buffer[6] = static_cast<uint8_t>((v >> 48) & max_byte);
buffer[7] = static_cast<uint8_t>((v >> 56) & max_byte);
#endif
这将确保根据处理器架构处理long,而不是强制长到64位
3.对于提供的代码
void func(unsigned long v)
{
union {
unsigned long long ival;
unsigned char cval[8];
} a;
a.ival = v;
}
当然,如果您使用c ++,那么您可以通过修改上述内容,以类似的方式存储任何基本数据类型:
template<class I>
void func(I v) {
union {
unsigned long long ival;
unsigned char cval[8];
I val;
} a;
a.val = v;
}