指针算术是否在联合UB的非活动成员上?

Oli*_*liv 12 c++ pointer-arithmetic language-lawyer c++11

我们来考虑这个示例代码:

struct sso
{
    union {
        struct {
            char* ptr;
            char size_r[8];
        } large_str;
        char short_str[16];
    };

    const char* get_tag_ptr() const {
        return short_str+15;
    }
};
Run Code Online (Sandbox Code Playgroud)

[basic.expr]中指定只要结果指向数组的另一个元素(或超过对象的末尾或最后一个元素),就允许指针运算.尽管如此,如果数组是联合的非活动成员,则在本节中未指定会发生什么.我相信这不是问题short_str+15,永远不是UB.这样对吗?

以下问题清楚地表明了我的意图

YSC*_*YSC 5

写入时return short_str+15;,您获取其生命周期可能尚未开始的对象的地址,但除非您取消引用它,否则不会导致未定义的行为.

[basic.life]/1.2

如果对象是联合成员或其子对象,则其生命周期仅在该联合成员是联合中的初始化成员时开始,或者如下所述[class.union].

[class.union]/1

在联合中,如果非静态数据成员的名称指的是其生命周期已开始且尚未结束的对象([basic.life]),则该成员处于活动状态.联合类型对象的至多一个非静态数据成员在任何时候都可以是活动的,也就是说,任何时候最多一个非静态数据成员的值都可以存储在并集中.

[basic.life]/6

在对象的生命周期开始之前但是在对象占用的存储空间已经被分配之后,或者在对象的生命周期结束之后以及在重用或释放对象占用的存储之前,任何表示对象的地址的指针可以使用对象将位于或位于的存储位置,但仅限于有限的方式.对于正在建造或毁坏的物体,请参阅[class.cdtor].否则,这样的指针引用已分配的storage([basic.stc.dynamic.allocation]),并且使用指针就好像指针的类型为void*一样,是明确定义的.允许通过这样的指针的间接,但是得到的左值可以仅以有限的方式使用,如下所述.
- [与工会无关的名单]

  • 你确定`short_str + 15`确实"使用指针就像指针是'void*`'类型一样吗? (2认同)