以与标准数组相同的方式重新解释结构与数组相同类型的成员 [英] Reinterpret struct with members of the same type as an array in a standard compliant way

查看:104
本文介绍了以与标准数组相同的方式重新解释结构与数组相同类型的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在各种3d数学代码库中,我有时会遇到如下情况:

In various 3d math codebases I sometimes encounter something like this:

struct vec {
    float x, y, z;

    float& operator[](std::size_t i)
    {
        assert(i < 3);
        return (&x)[i];
    }
};

其中AFAIK是非法的,因为允许实现在成员之间虚假地添加填充,即使它们是同一类型,尽管实际上没有这样做.

Which, AFAIK is illegal because implementations are allowed to spuriously add padding between members, even if they are of the same type, though none will do so in practice.

通过通过static_assert施加约束可以使这合法吗?

Can this be made legal by imposing constraints via static_asserts?

static_assert(sizeof(vec) == sizeof(float) * 3);

static_assert不被触发是否暗示operator[]符合预期并且在运行时不调用UB?

I.e. does static_assert not being triggered implies operator[] does what is expected and doesn't invoke UB at runtime?

推荐答案

不,这是不合法的,因为在将整数添加到指针时,以下情况适用([expr.add]/5):

No, it is not legal because when adding an integer to a pointer, the following applies ([expr.add]/5):

如果指针操作数和结果都指向同一数组对象的元素,或者指向过去 数组对象的最后一个元素,求值不应产生溢出;否则,行为是 未定义.

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

yx末尾占据一个存储位置(被视为具有一个元素的数组),因此定义了将&x加1,但是未定义将2添加到&x.

y occupies the memory location one past the end of x (considered as an array with one element) so adding 1 to &x is defined, but adding 2 to &x is undefined.

这篇关于以与标准数组相同的方式重新解释结构与数组相同类型的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆