想象一下以下情况:
给出了一个uint8_t类型的4个元素的数组,它们逐字节表示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+aligned+pointer+types
上面的代码可以编译,并在我尝试过的最新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标准,这样的代码安全又可移植吗?
如果我做出了错误的假设或错误地解释了某些内容,请告诉我。
答案 0 :(得分:1)
在这种情况下,如果我们取消引用uint32_t指针,则在某些体系结构上可能会崩溃。
这是正确的。不,此代码不安全,并且出于您所描述的确切原因,也无法移植。