【发布时间】:2015-09-01 15:35:02
【问题描述】:
我有以下简单的程序,它使用联合在 64 位整数与其对应的字节数组之间进行转换:
union u
{
uint64_t ui;
char c[sizeof(uint64_t)];
};
int main(int argc, char *argv[])
{
u test;
test.ui = 0x0123456789abcdefLL;
for(unsigned int idx = 0; idx < sizeof(uint64_t); idx++)
{
cout << "test.c[" << idx << "] = 0x" << hex << +test.c[idx] << endl;
}
return 0;
}
我期望的输出是:
test.c[0] = 0xef
test.c[1] = 0xcd
test.c[2] = 0xab
test.c[3] = 0x89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
但我实际得到的是:
test.c[0] = 0xffffffef
test.c[1] = 0xffffffcd
test.c[2] = 0xffffffab
test.c[3] = 0xffffff89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
我在带有 GCC 的 Ubuntu LTS 14.04 上看到了这一点。
一段时间以来,我一直在努力解决这个问题。为什么 char 数组的前 4 个元素显示为 32 位整数,并在它们前面加上 0xffffff?为什么只有前 4 个,为什么不是全部?
有趣的是,当我使用数组写入流(这是整个事情的最初目的)时,会写入正确的值。但是通过char比较数组char显然会导致问题,因为前4个char不等于0xef、0xcd等等。
【问题讨论】:
-
转换为
(char*)然后读取4个字节...? -
没有变化。此外,我总是可以用 0x000000ff 屏蔽字符以获得预期值。我只是对这种行为背后的原因感兴趣。
-
显然您的实现已签名字符。普通整数提升将符号扩展。
-
我认为这是因为 test.c 是
int类型,这将是 16 位、32 位或 64 位字,具体取决于内核构建的体系结构......有点不过,猜测一下,我需要掸掉我的 C++ 帽子!此外,对于 @ewd 的评论,您可能希望将其明确转换为(unsigned int)或(unsigned char)。 -
嘿,解决了!谢谢!