假设我有'numb'=1025 [00000000 00000000 00000100 00000001]代表的数字:
在Little-Endian机器上:
00000001 00000100 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
在Big-Endian机器上:
00000000 00000000 00000100 00000001
Run Code Online (Sandbox Code Playgroud)
现在,如果我在10位上应用Left Shift(即:numb << = 10),我应该:
[A]在Little-Endian机器上:
正如我在GDB中注意到的那样,Little Endian通过3个步骤执行左移:[我已经显示'3'步骤以更好地理解处理]
对待没有.在Big-Endian公约中:
00000000 00000000 00000100 00000001
Run Code Online (Sandbox Code Playgroud)应用左移:
00000000 00010000 00000100 00000000
Run Code Online (Sandbox Code Playgroud)再次在Little-Endian中表示结果:
00000000 00000100 00010000 00000000
Run Code Online (Sandbox Code Playgroud)[B].在Big-Endian机器上:
00000000 00010000 00000100 00000000
Run Code Online (Sandbox Code Playgroud)
我的问题是:
如果我直接在Little Endian公约上应用左移,它应该给:
numb:
00000001 00000100 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
numb << 10:
00010000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
但实际上,它给出了:
00000000 00000100 00010000 00000000
Run Code Online (Sandbox Code Playgroud)
为了达到第二个结果,我在上面展示了三个假设步骤.
请解释一下为什么上述两个结果不同:实际结果numb << 10与预期结果不同.
在回答另一个问题时,我想到了以下示例:
void *p;
unsigned x = 17;
assert(sizeof(void*) >= sizeof(unsigned));
*(unsigned*)&p = 17; // (1)
memcpy(&p, &x, sizeof(x)); // (2)
Run Code Online (Sandbox Code Playgroud)
第1行打破了别名规则.然而,第2行是好的.别名规则.问题是:为什么?编译器是否具有关于memcpy等函数的特殊内置知识,还是有一些其他规则可以使memcpy正常运行?有没有办法在标准C中实现类似memcpy的函数而不破坏别名规则?