正在使用reinterpret_cast(在非活动成员中)强制转换为联合 UB 的活动成员
Is using reinterpret_cast (in a non-active-member) to cast to the active member of an union UB?
看看这个片段:
#include <new>
struct Storage {
int value;
Storage() : value(0) { }
};
struct Field {
void set(int v) {
reinterpret_cast<Storage *>(this)->value = v;
}
};
union Foo {
Storage storage;
Field field;
Foo() {
new(&storage) Storage;
}
};
int main() {
Foo f;
f.field.set(1);
}
在main
中,f
有活动成员storage
。然后,在不同的成员(field
)上,有一个函数调用(set
),它将this
转换为活动成员的类型。
此代码有 UB 吗?
对f.field.set
的调用违反了 [class.mfct.non-static]p2:
如果为非当您类型
X
的对象调用类X
的非静态成员函数,或者不是从X
派生的类型,则行为是未定义的。
没有类型 Field
的对象时,您正在调用类set
的成员函数Field
。
此程序具有未定义的行为,因为您不能调用当前未处于活动状态的对象的非静态成员函数。 C++14 [basic.life]/6:
类似地,在对象的生存期开始之前,但在分配了对象将占用的存储之后,或者在对象的生存期结束之后,在对象占用的存储被重用或释放之前,任何涉及原始对象的glvalue都可以使用,但只能以有限的方式使用。 在以下情况下,程序具有未定义的行为:
。
glvalue 用于访问非静态数据成员或调用对象的非静态成员函数
。
相关文章:
- 从成员指针到整个结构/类的强制转换
- 将方法转换为调用该方法的成员函子对象会导致崩溃
- 从类成员函数到类 C 函数指针的转换
- 静态成员变量不会由 gettext 转换
- 指针类型类成员的动态强制转换的恒定性是什么?
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 转换模板中的成员函数指针
- 传递可变参数时在成员初始值设定项列表中强制转换
- 将函数强制转换为成员函数
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 指向类成员函数的指针中存在类型转换错误
- 在不复制数据的情况下,将double数组转换为只有double成员的structs数组
- 指向数据成员转换的 Constexpr 指针
- 模板成员转换运算符,默认模板参数到与 TypeName 绑定的函数
- 将 TEXTRANGE 结构的 lpstrtext 成员转换为多字节字符集
- 模板成员转换运算符中的编译错误
- 类成员转换函数id
- std::unique_ptr结构成员转换为结构类型
- 将 Object int 数据成员转换为浮点数并划分会将奇怪的数据 cout 附加到控制台
- 怎样才能轻松地将枚举成员转换为int类型?