Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

c++ - Is pointer arithmetic on inactive member of a union UB?

Let's consider this example code:

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;
    }
};

In [basic.expr] it is specified that pointer arithmetic is allowed as long as the result points to another element of the array (or past the end of an object or of the last element). Nevertheless it is not specified in this setion what happens if the array is an inactive member of a union. I believe it is not an issue short_str+15 is never UB. Is it right?

The following question clearly showes my intent

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Writing return short_str+15;, you take the address of an object whose lifetime may have not started, but this does not result in undefined behavior unless you dereference it.

[basic.life]/1.2

if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union, or as described in [class.union].

and

[class.union]/1

In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

but

[basic.life]/6

Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.allocation]), and using the pointer as if the pointer were of type void* , is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below.
- [list unrelated to unions]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...