正在读取与活动联盟成员相同类型的非活动联盟成员明确定义
Is reading inactive union member of the same type as active one well-defined?
请考虑以下结构:
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 的类型,如 vec4
、vec2
等。
但是,尽管预期的用途是使这成为可能
vec4 a(1,2,4,7);
a.x=7;
a.b=a.r;
,这似乎是一种未定义的行为,因为,正如这里引用的,
在联合中,最多一个数据成员可以随时处于活动状态,也就是说,最多一个数据成员的值可以随时存储在联合中。
例如,使用仅定义如下结构不是更好吗?
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;
}
};
还是我在解决一个不存在的问题?是否有一些特殊声明允许访问相同类型的非活动工会成员?
我认为您所指的引文是针对在联盟中具有不同的类型。
struct foo {
union {
float x,
int y,
double z,
};
};
这些是不同的数据,方便地存储到相同的结构中,联合不应该是一种铸造机制。
GLM 方法使用相同的数据,并将并集用于别名机制。
你的方法可能C++"更好",但它更糟糕的"工程"。矢量数学需要快速,在这种情况下越小越好。
您的实现是使向量大 3 倍。 sizeof(glm::vec4); // 16
同时sizeof(your_vec4); // 48 - ouch
如果您在哪里处理大量这些,这种情况经常发生,3 倍以上的缓存未命中与your_vec4
.
我认为你是对的,虽然 glm 使用联合作为别名有点多,虽然我不确定它是否未定义,但这种事情我已经看到了很多没有太大问题,并且 glm 被广泛使用。
我真的不认为有必要在C++中模拟 glsl,struct { float x,y,z,w; }
会更好(至少在我看来)。
相关文章:
- 如何在QT中为QInputDialog输入密码时设置背景非活动和灰色?
- 是匿名联盟成员平等的指示
- 使用 std::launder 从指向非活动工会成员的指针获取指向活动工会成员的指针?
- 使用 std::launder 从指向非活动对象的指针获取指向活动对象成员的指针?
- 正在使用reinterpret_cast(在非活动成员中)强制转换为联合 UB 的活动成员
- 指向成员非类型模板参数的指针的实际用法
- 根据不同的类型,联盟成员仅在一个类中
- 取参考成员(非 POD)的偏移量
- 当应用程序变为活动/非活动状态时获取通知
- 取消引用指向联盟成员的指针
- Win32逻辑块预处理器显示为非活动状态
- 访问非活动的联合成员和未定义的行为
- 如何在不破坏非活动选择颜色的情况下更改 wxTextCtrl 的背景颜色
- QPushButton 处于非活动状态,直到 MainWindow 获得焦点
- 访问联合中相同类型的非活动成员
- 问题:如何在非活动窗口中显示所选文本
- 松弛常量表达式中并集的非活动成员的左值到右值转换的解决方法
- 将非活动std::unique_ptr数据成员交换为联合
- 正在读取与活动联盟成员相同类型的非活动联盟成员明确定义
- CPP 私有数据成员SDL_Rect非活动状态