在C语言中将字符数组强制转换为int是否安全?

时间:2018-10-04 16:59:59

标签: c pointers casting portability

想象一下以下情况:

给出了一个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标准,这样的代码安全又可移植吗?

如果我做出了错误的假设或错误地解释了某些内容,请告诉我。

1 个答案:

答案 0 :(得分:1)

  

在这种情况下,如果我们取消引用uint32_t指针,则在某些体系结构上可能会崩溃。

这是正确的。不,此代码不安全,并且出于您所描述的确切原因,也无法移植。