gpt4 book ai didi

警告 “dereferencing type-punned pointer will break strict-aliasing rules” 的后果

转载 作者:行者123 更新时间:2023-12-04 17:48:45 24 4
gpt4 key购买 nike

我已经对类似主题和一些与之相关的 Material 进行了一些查询。
但我的查询主要是为了了解以下代码的警告。我不想修复!!
我理解有两种方式,一个 union 或使用 memcpy .

uint32 localval;
void * DataPtr;
localval = something;
(*(float32*)(DataPtr))= (*(const float32*)((const void*)(&localval)));

请注意以下要点
1.这里的转换涉及的两种类型都是32位。 (还是我错了?)
2. 都是局部变量。

编译器具体要点:
1.代码应该是平台无关的,这是一个要求!!
2. 我在 GCC 上编译,它按预期工作。 (我可以将 int 重新解释为浮点数),这就是我忽略警告的原因。

我的问题
1. 在这种别名情况下,编译器可以执行哪些优化?
2. 由于两者都占用相同的大小(如果不是,请纠正我)这种编译器优化的副作用是什么?
3. 我可以安全地忽略警告或关闭别名吗?
4. 如果编译器没有进行优化并且我的程序在我第一次编译后没有损坏?我可以安全地假设每次编译器都会以相同的方式运行(不进行优化)吗?
5. 别名是否也适用于 void * 类型转换?还是仅适用于标准类型转换(int、float 等...)?
6. 禁用别名规则有什么影响?

已编辑
1. 基于 R 和 Matt McNabb 的更正
2.新增 问题

最佳答案

您有一个不完整的示例(如所写,由于 localval 未初始化,因此显示为 UB)所以让我完成它:

uint32 localval;
void * DataPtr;
DataPtr = something;
localval = 42;
(*(float32*)(DataPtr))= (*(const float32*)((const void*)(&localval)));

现在,由于 localval有类型 uint32*(const float32*)((const void*)(&localval))有类型 float32 ,它们不能别名,因此编译器可以自由地重新排列最后两个语句。这显然会导致行为与您想要的不同。

正确的写法是:
memcpy(DataPtr, &localval, sizeof localval);

关于警告 “dereferencing type-punned pointer will break strict-aliasing rules” 的后果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23821256/

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