c++ - 读取与事件成员类型相同的非事件联盟成员是否定义明确?

标签 c++ undefined-behavior unions

<分区>

考虑以下结构:

struct vec4
{
    union{float x; float r; float s};
    union{float y; float g; float t};
    union{float z; float b; float p};
    union{float w; float a; float q};
};

类似这样的东西似乎被用在了例如GLM提供类似 GLSL 的类型,如 vec4vec2 等。

但是尽管预期的用途是使这成为可能

vec4 a(1,2,4,7);
a.x=7;
a.b=a.r;

,这似乎是一个未定义的行为,因为,如引用 here ,

In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time.

例如,不是更好吗?只需定义如下所示的结构?

struct vec4
{
    float x,y,z,w;
    float &r,&g,&b,&a;
    float &s,&t,&p,&q;
    vec4(float X,float Y,float Z,float W)
        :x(X),y(Y),z(Z),w(W),
         r(x),g(y),b(z),a(w),
         s(x),t(y),p(z),q(w)
    {}
    vec4()
        :r(x),g(y),b(z),a(w),
         s(x),t(y),p(z),q(w)
    {}
    vec4(const vec4& rhs)
        :x(rhs.x),y(rhs.y),z(rhs.z),w(rhs.w),
         r(x),g(y),b(z),a(w),
         s(x),t(y),p(z),q(w)
    {}
    vec4& operator=(const vec4& rhs)
    {
        x=rhs.x;
        y=rhs.y;
        z=rhs.z;
        w=rhs.w;
        return *this;
    }
};

或者我是在解决一个不存在的问题?是否有一些特殊的声明允许访问相同类型的非事件 union 成员?

最佳答案

我认为您所引用的引文是针对在 union 中使用不同的类型。

struct foo {
  union {
    float x,
    int y,
    double z,
  };
};

这些是不同的数据,方便地存储在相同的结构中, union 不应该是一种转换机制。

GLM 方法使用相同的数据并将 union 用于别名机制。

您的方法可能是“更好”的 C++,但更糟糕的是“工程”。 vector 数学需要快速,在这种情况下越小越好。

您的实现是使 vector 大 3 倍。 sizeof(glm::vec4);//16sizeof(your_vec4);//48 - ouch 如果您在处理大量此类数据(通常是这种情况),则 your_vec4 的缓存未命中数是原来的 3 倍。

我认为你是对的,虽然 glm 使用 union 作为别名有点多,虽然我不确定它是否未定义,但这种类型的事情我已经看到很多没有太多问题,并且 glm 被广泛使用.

我真的不认为有必要在 C++ 中模拟 glsl,struct { float x,y,z,w; 会更好(至少在我看来)。

关于c++ - 读取与事件成员类型相同的非事件联盟成员是否定义明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30826943/

相关文章:

c++ - 隐藏 SDL 窗口中的标题栏和框架

c++ - 在生产中使用 Address Sanitizer 或其他未定义的行为 sanitizer ?

go - Go 中联合的最佳实践

c - 如何检查 c 中未定义的行为?

c++ - 是否有隐式返回值的 GCC 扩展?

c - C 变量中需要的垃圾值

包含结构的 C union - 内存映射 - 编译器跳过一个字节?

c++ - 在不使用乘法和除法运算符的情况下如何计算A到幂B?

c++ - 插入到特里

c++ - typedef 的前向声明