通过指向班级第一个成员的指针访问成员是不确定的行为吗?
Is it undefined behavior to access members through a pointer to the first member of the class
我正在玩一堂课,我想用operator[]
索引其中,同时也能够访问字段。
我已经在我想做的事情下附加了一个mcve,它可以通过变量本身访问成员变量,还可以使用一些指针偏移(例如:如果有a
和b
,然后,我可以通过名称访问b
,或者如果它们的类型相同,并且在没有填充的情况下使用&a + 1
,则可以访问它。
我担心我会遇到不确定的行为,并且不会知道。最初,我试图进行"与1)浮子成员以及2)浮子数组进行结合",但我发现这是不确定的行为。如果我要在下面要做的事情是未定义的,但找不到它(这显然并不意味着它不存在,我很容易错过它)。
由于我也使用CRTP来做到这一点,所以我认为我要自行施放,只要继承不提供任何成员。
。为了确保在C 中可能是合法的,我添加了一堆静态断言:
- 确保它是标准布局,因此我可以将Offsetof用于其他静态断言
static_assert(std::is_standard_layout_v<Color>);
- 确保这是微不足道的
static_assert(std::is_trivial_v<Color>);
- 确保偏移是顺序的
static_assert(offsetof(Color, r) == 0);
,static_assert(offsetof(Color, g) == sizeof(float));
,static_assert(offsetof(Color, b) == 2 * sizeof(float));
- 确保从继承
static_assert(sizeof(Color) == 3 * sizeof(float));
中添加任何内容
代码:
#include <iostream>
using namespace std;
template <typename T>
class ColorCRTP {
T& getInstance() {
return *static_cast<T*>(this);
}
public:
// Is it UB to do this when we set values from the
// fields themselves in the actual class?
float& operator[](size_t index) {
// Assume the inheriting class *always* is only a
// series of sequential members of the exact same
// type.
return *(&getInstance().r + index);
}
};
struct Color : ColorCRTP<Color> {
float r;
float g;
float b;
Color() = default;
Color(float r, float g, float b) : r(r), g(g), b(b) { }
};
// Do these help guarantee that I am not performing UB?
static_assert(std::is_standard_layout_v<Color>);
static_assert(std::is_trivial_v<Color>);
static_assert(offsetof(Color, r) == 0);
static_assert(offsetof(Color, g) == sizeof(float));
static_assert(offsetof(Color, b) == 2 * sizeof(float));
static_assert(sizeof(Color) == 3 * sizeof(float));
int main() {
Color c{0.5f, 0.75f, 1.0f};
c.g = 0.123f;
cout << c[1] << " = " << c.g << endl;
c[1] = 0.321f; // This is legal or UB?
cout << c[1] << " = " << c.g << endl;
}
我是否违反了标准并通过执行上述行为来调用不确定的行为?假设当然没有范围的索引。
由于r
是第一个成员,我不知道6.7.2第4.3部分是否给我进一步的安慰,因为我是否以安全的方式引用了第一个成员。
程序的行为不确定。
指针算术仅在数组中有效。和r
,g
,b
不形成数组。
最好的选择是用包含3个标签的switch
块回顾float& operator[](size_t)
。
相关文章:
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 不确定如何装饰我的C++库代码以在 C 中使用
- C++功能泄漏内存,我是C++新手,不确定如何解决
- "错误 C0000:语法错误,令牌"<EOF>"处出现意外$end,并且不确定
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- 为什么以下代码是不确定的?
- 为什么 operator() 处的指针成员不起作用?
- 编译错误:"lvalue required as left operand of assignment" 不确定原因
- 误用指针会产生分段错误。我仍然不确定如何纠正它
- 我不确定为什么代码没有运行,它在编译时抛出错误,说它无法找到 PrintArray()
- C++ 成员不是变量,而只是数据类型的名称吗?
- 通过指向班级第一个成员的指针访问成员是不确定的行为吗?
- 不确定如何修复;非静态成员参考必须相对于特定对象
- 通过全球常数对静态数据成员的初始化会导致不确定的行为
- 在初始评估列表中引用类成员是不确定的行为吗?
- 类中成员变量的数量不确定?C++
- 在其成员函数返回之前,将对象删除是不确定的行为吗?
- 如果没有使用使用代码的链接,则对G 中的静态常规成员的不确定引用
- 如何使大小不确定的多维数组成为 c++ 中类的成员