gpt4 book ai didi

c - 使用 uint16_t* 访问 uint32_t 数组会导致未定义的行为吗?

转载 作者:太空宇宙 更新时间:2023-11-04 01:55:30 24 4
gpt4 key购买 nike

我有以下表面上很简单的 C 程序:

#include <stdint.h>
#include <stdio.h>

uint16_t
foo(uint16_t *arr)
{
unsigned int i;
uint16_t sum = 0;

for (i = 0; i < 4; i++) {
sum += *arr;
arr++;
}

return sum;
}

int main()
{
uint32_t arr[] = {5, 6, 7, 8};
printf("sum: %x\n", foo((uint16_t*)arr));

return 0;
}

我们的想法是迭代一个数组并将它的 16 位字相加,忽略溢出。当使用 gcc 在 x86-64 上编译此代码且未进行优化时,我得到的结果似乎是 0xb (11) 的正确结果,因为它对前 4 个 16 位字(包括 5 和 6)求和:

$ gcc -O0 -o castit castit.c
$ ./castit
sum: b
$ ./castit
sum: b
$

有了优化就另当别论了:

$ gcc -O2 -o castit castit.c
$ ./castit
sum: 5577
$ ./castit
sum: c576
$ ./castit
sum: 1de6

程序为总和生成不确定的值。

我假设它现在不是编译器错误,这会让我相信程序中存在一些未定义的行为,但我无法指出会导致它的具体原因。

请注意,当函数 foo 被编译为单独链接的模块时,问题就不会出现。

最佳答案

你正在破坏 strict aliasing rule ,这确实是 UB。那是因为你通过不同类型的指针为 uint32_t 的数组 arr 别名,即 uint16_t 在将它传递给 foo(uint16_t* )

唯一可用于别名其他类型的指针类型是 char*

关于该主题的一些额外阅读 Material :http://dbp-consulting.com/tutorials/StrictAliasing.html

关于c - 使用 uint16_t* 访问 uint32_t 数组会导致未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34913559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com