相关疑难解决方法(0)

我可以在C++中安全地将浮点数结构转换为浮点数组吗?

例如,我有这个结构

struct  A {
    float x;
    float y;
    float z;
};
Run Code Online (Sandbox Code Playgroud)

我可以这样做吗?A a; float* array = (float*)&a; 并使用as float数组?

c++

30
推荐指数
4
解决办法
2640
查看次数

通过C转换访问结构的第一个字段是否违反了严格的别名?

此代码是否违反严格别名?

struct {int x;} a;
*(int*)&a = 3
Run Code Online (Sandbox Code Playgroud)

更抽象的是,只要原始读/写操作类型正确,在不同类型之间进行转换是否合法?

c c++ strict-aliasing language-lawyer reinterpret-cast

15
推荐指数
1
解决办法
1666
查看次数

以符合标准的方式使用与数组相同类型的成员重新解释struct

在各种3d数学代码库中,我有时会遇到这样的事情:

struct vec {
    float x, y, z;

    float& operator[](std::size_t i)
    {
        assert(i < 3);
        return (&x)[i];
    }
};
Run Code Online (Sandbox Code Playgroud)

其中,AFAIK是非法的,因为允许实现在成员之间虚假地添加填充,即使它们属于同一类型,但实际上没有人会这样做.

通过static_asserts 施加约束可以使这变得合法吗?

static_assert(sizeof(vec) == sizeof(float) * 3);
Run Code Online (Sandbox Code Playgroud)

static_assert没有被触发意味着operator[]什么是预期的并且不会在运行时调用UB?

c++ strict-aliasing language-lawyer type-punning structure-packing

9
推荐指数
1
解决办法
728
查看次数

可以使用const变量避免混淆问题

我的公司使用消息服务器将消息const char*收集到a中,然后将其转换为消息类型.

在提出这个问题之后,我对此感到担忧.我不知道消息服务器中有任何不良行为.const变量是否可能不会出现锯齿问题?

例如,假设foo是以下列MessageServer方式之一定义的:

  1. 作为参数: void MessageServer(const char* foo)
  2. 或者作为顶部的const变量MessageServer:const char* foo = PopMessage();

现在MessageServer是一个巨大的功能,但它从来没有指派任何事情foo在1点但是,MessageServer的逻辑foo 被转换为所选择的消息类型.

auto bar = reinterpret_cast<const MessageJ*>(foo);
Run Code Online (Sandbox Code Playgroud)

bar 将仅从随后读取,但将广泛用于对象设置.

这里是否存在别名问题,或者foo只是初始化并且从未修改过的事实会保存我吗?

编辑:

Jarod42的回答中找到与从铸造没有问题const char*MessageJ*,但我不知道这是有道理的.

我们知道这是非法的:

MessageX* foo = new MessageX;
const auto bar = reinterpret_cast<MessageJ*>(foo);
Run Code Online (Sandbox Code Playgroud)

我们是否以某种方式说这是合法的?

MessageX* foo = new MessageX;
const auto temp = reinterpret_cast<char*>(foo);
auto bar = reinterpret_cast<const MessageJ*>(temp); …
Run Code Online (Sandbox Code Playgroud)

c++ alias const strict-aliasing reinterpret-cast

6
推荐指数
1
解决办法
903
查看次数