【问题标题】:Is reading inactive union member of the same type as active one well-defined? [duplicate]读取与活动成员相同类型的非活动联合成员是否定义明确? [复制]
【发布时间】:2015-06-14 07:24:49
【问题描述】:

考虑以下结构:

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

在一个联合中,任何时候最多可以有一个数据成员处于活动状态,即任何时候最多可以有一个数据成员的值存储在一个联合中。

难道不是更好吗?使用只需定义类似以下的结构吗?

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;
    }
};

还是我正在解决一个不存在的问题?是否有一些特殊的声明允许访问相同类型的非活动工会成员?

【问题讨论】:

    标签: c++ undefined-behavior unions


    【解决方案1】:

    我认为您所指的引用是针对在联合中具有不同类型的。

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

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

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

    您的方法可能是“更好的”C++,但它的“工程”更差。矢量数学需要很快,在这种情况下越小越好。

    您的实现是使向量大 3 倍。 sizeof(glm::vec4); // 16sizeof(your_vec4); // 48 - ouch 如果您在处理大量此类问题(通常是这种情况),your_vec4 的缓存未命中率会增加 3 倍。

    我认为你是对的,虽然 glm 使用联合作为别名有点多,虽然我不确定它是否未定义,但这种类型的东西我见过很多没有太多问题,而且 glm 被广泛使用.

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 2018-09-21
      • 2019-10-11
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多