gpt4 book ai didi

c - 严格的别名规则,假阳性还是假阴性?

转载 作者:行者123 更新时间:2023-12-04 09:40:14 24 4
gpt4 key购买 nike

我在 C 中遇到严格别名问题。我使用的是 GCC 4.7.1。

例子一:
使用 -fstrict-aliasing -Wstrict-aliasing=3 编译此代码时,我收到“警告:取消引用类型双关指针将破坏严格别名规则”

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

int main(void)
{
uint8_t a[4] = {0x01, 0x23, 0x45, 0x67};
uint32_t b;

b = *(uint32_t *)a;

printf("%x\n", b);

return(0);
}


例子二:
此代码不使用 -fstrict-aliasing 和 -Wstrict-aliasing=3 或 -Wstrict-aliasing=2 或 -Wstrict-aliasing=1 给出警告

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

int main(void)
{
uint8_t a[4] = {0x01, 0x23, 0x45, 0x67};
uint32_t b;
void *p;

p = a;
b = *(uint32_t *)p;

printf("%x\n", b);

return(0);
}


这两个示例都可以正常工作。

使用 union 也是未定义的行为,在我的情况下使用 memcpy() 太慢了。
那么,第一个示例是安全的(误报)还是第二个示例也不安全(误报)或...?

谢谢。

最佳答案

如果您想从 4 个 uint8_t 制造一个 uint32_t,那么就这样做:制造它。不要试图通过指针转换从不是一个的东西中拉出一个。您提供的代码的结果会有所不同,具体取决于您的平台是小端还是大端,更不用说它完全错误了。

他们不好。无论如何,提供的两种 sample 都是不安全的。此类强制转换绕过了数据对齐要求。如果你转换“到”的任何东西比你转换“来自”的任何东西可能需要更严格的对齐,那么你就会引发总线错误。注意最初的警告。指向 void 的中间指针只是掩盖了问题(就像大多数问题一样)。

当您构建 uin32_t 时,您想要知道什么字节去“哪里”。

uint8_t a[4] = {0x01, 0x23, 0x45, 0x67};
uint32_t b = ((uint32_t)a[0] << 24) |
((uint32_t)a[1] << 16) |
((uint32_t)a[2] << 8) |
(uint32_t)a[3];

这将总是将 a[0] 字节放在目标 32 位无符号的高字节中,将 a[1] 放在下一个字节中,依此类推,而不管字节顺序如何。 b始终0x01234567

关于c - 严格的别名规则,假阳性还是假阴性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13708639/

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