gpt4 book ai didi

c++ - 类型双关、char[] 和取消引用

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:12 25 4
gpt4 key购买 nike

我有一个旨在存储用户定义数据(即来自插件)的结构。它有一个这样的 char[],它具有给定的最大大小来存储该数据。

struct A
{
// other members omitted
// data meant to be type punned, only contains PODs
char data[256];
};

然后是一个示例用户结构,它有一个静态函数,可以从 A 转换自身。

struct B
{
int i;
double d;

static B& FromA_ref(A& a)
{
// static_assert that sizeof(B) < sizeof(A::data)
return * reinterpret_cast<B*>(a.data);
}
};

我用 g++ -O3 -std=c++0x -Wall -o test test.cpp (GCC 4.6.1) 编译。

这会触发一个解引用类型双关指针将打破严格别名规则警告。我认为这没问题,因为我使用了 char[] 作为存储,我认为它遵循与 char* 相同的规则。我觉得很奇怪,它没有。不是吗?好吧,...我现在无法更改它,所以让我们继续吧。

现在让我们考虑以下方法:

struct B
{
....
static B* FromA_ptr(A& a)
{
// static_assert that sizeof(B) < sizeof(A::data)
return reinterpret_cast<B*>(a.data);
}
}

因为我没有在此处取消引用任何内容,GCC 不会输出任何警告。当我稍后使用指向 B 的指针时,它也不会。

A a;
auto b = B::FromA_ptr(a);
b->i = 2; // no warnings.

但是这样做安全吗?我觉得我一直在努力解决问题而不是解决问题。对我来说,-> 仍然以某种方式取消引用变量。

或者,有没有更好的方法来达到这个效果? IE。从另一个结构中的存储获取可修改的引用(或指针)? ( union 将无法工作,因为在定义 A 时存储的类型集是未知的,并且一些可以通过插件添加,memcpy 将迫使我复制尽管这似乎是迄今为止唯一安全的方式来回传输数据)

最佳答案

答案是否定的,它不安全(参见 SO question )

GCC will assume that the pointers cannot alias. For instance, if you assign through one then read from the other, GCC may, as an optimisation, reorder the read and write - I have seen this happen in production code, it is not pleasant to debug.

attribute((may_alias)) on the types used is probably the closest you can get to disabling the assumption for a particular section of code.

关于c++ - 类型双关、char[] 和取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9985873/

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