想象一下以下情况:
给出了一个包含 4 个 uint8_t 类型元素的数组,逐字节表示 32 位整数。目标是将整个数组寻址为 32 位整数。
int main( void )
{
uint8_t array[4] = { 0, 0, 0, 12 };
uint32_t * ptr = ( uint32_t * )array;
printf("%d", *ptr);
return 0;
}
现在忘记字节序,它与问题无关(我不认为)。
现在 C 标准说将指针转换为具有更严格对齐的类型是未定义的行为。
这里给出了一些兼容和不兼容代码的例子:https : //wiki.sei.cmu.edu/confluence/display/c/EXP36-C.+Do+not+cast+pointers+into+more+strictly+对齐+指针+类型
上面的代码在我尝试过的最新 GCC 和 IAR 编译器上编译并给出了预期的结果。
问题是这段代码通常是否安全?
我想象在整数类型是自对齐的架构上的以下情况。我的逻辑是,由于数组将继承其最严格类型的对齐规范 - char 它可以放置在内存中的任何位置。例如:
Memory | Value | integer can start here
....
0x20 | | yes
0x21 | 0 | no <- array begins, uint32_t ptr
0x22 | 0 | no
0x23 | 0 | no
0x24 | 12 | yes
....
在这种情况下,如果我们取消引用 uint32_t 指针,我们可能会在某些架构上崩溃。
我在这里错过了什么吗?显然,这段代码适用于主要编译器,我认为它失败的情况非常具体,与遗留体系结构和编译器更相关。然而,根据 C 标准,这样的代码是否安全且可移植?
如果我做出了不正确的假设或错误地解释了某些内容,请告诉我。
在这种情况下,如果我们取消引用 uint32_t 指针,我们可能会在某些架构上崩溃。
这是对的。不,此代码不安全,并且由于您描述的原因,它不可移植。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句