在 C 中将字符数组转换为 int 是否安全?
Is it safe to cast array of chars to int in C?
想象一下以下情况:
给出了一个包含 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+aligned+pointer+types
上面的代码在我尝试过的最新 GCC 和 IAR 编译器上编译并给出了预期的结果。
问题是这个代码一般来说是否安全?
我想象在整数类型自对齐的体系结构上的以下情况。我的逻辑是,由于 array 将继承其最严格类型的对齐规范 - 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标准的安全性和可移植性?
如果我做出了不正确的假设或对某些内容的解释不正确,请告诉我。
In this scenario if we dereference a uint32_t pointer we may potentially crash on some architectures.
这是正确的。不,由于您描述的原因,此代码不安全且不可移植。
想象一下以下情况:
给出了一个包含 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+aligned+pointer+types
上面的代码在我尝试过的最新 GCC 和 IAR 编译器上编译并给出了预期的结果。
问题是这个代码一般来说是否安全?
我想象在整数类型自对齐的体系结构上的以下情况。我的逻辑是,由于 array 将继承其最严格类型的对齐规范 - 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标准的安全性和可移植性?
如果我做出了不正确的假设或对某些内容的解释不正确,请告诉我。
In this scenario if we dereference a uint32_t pointer we may potentially crash on some architectures.
这是正确的。不,由于您描述的原因,此代码不安全且不可移植。