New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[class.copy.ctor] p15 Only the corresponding active object can be created and copied from the source #5193
Comments
[basic.life]/1:
The intent is more like
except that we may not want to start the lifetime of objects of a non-implicit-lifetime type (and everything nested within them), e.g. a union U { unsigned char buf[9000]; } u {};
auto* pv = new (&u.buf) std::vector<int> {};
U u2 = u; // do we want to start the lifetime of the object corresponding to *pv? Maybe not even create it? |
@languagelawyer Seems right, I think the last sentence is more accurate if it is that
Consider this example union U{
char c = 0;
int a;
} u; There are two objects nested within the object |
There is no first or second, the whole object representation of
|
@languagelawyer union U{
struct C{
int i;
struct X{} x;
} c = {0};
char c2;
};
U u1;
U u2 = u1; U::c::i and U::c::x are all subobjects of U::c, which in turn is a subobject of u1, they all within their lifetime. So, |
There is no such thing as direct or indirect subobject. NSDM is what can be direct or indirect. |
I meant the subobjects corresponding to indirect NSDMs or Base classes. Do these subobject conform to be |
Yes, why not. |
@languagelawyer Alright, I think your proposal looks good to me. |
@languagelawyer Hmmm... I still think we should completely say what these subobjects
However, this is different in a union class. Firstly, a union class cannot have any base class. There is also no provision that says that: the subobject of an object corresponding to the NSDM of a union is also a subobject of that union. union U{
struct X{ int a;} x;
} u;
|
It means members, not member subobjects.
I don't see the connection between the first and the second part.
And we don't want such provision. There is «nested within» relation for such transitivity.
We don't care whose subobject oS is, only is that it is a subobject. |
For the first opinion, since a subobject corresponding to a member is a member subobject, hence any subobject corresponding to a direct/indirect member is also a member subobject of the containing object. Do we indeed not care whether the object os is a subobject of the source object in the copy? Consider this example struct C{
int a = 0;
};
union U{
char buff[128];
};
U u = {0}; // start the lifetime of buff
new (u.buff + 4) C;
U u2 = u; Although, the created object by the new-expression is not a subobject of |
We want the «nested within» relation to be a tree, not a DAG, so an object corresponding to a base class (direct) NSDM is not a subobject of an object of derived type. (However, see #2310)
We do not care.
Check the definition of https://timsong-cpp.github.io/cppwp/n4868/intro.object#def:nested_within |
@languagelawyer I think I have seen your point. Did you mean
This may introduce an issue that if |
I think I wrote this several times: oS is just a subobject. Without "of". |
@languagelawyer Sorry. Maybe, I still don't understand your point. struct Vector{
int buff[2];
};
union U{
struct C{
char buff[1000];
int i;
struct X{} x;
} c = {0};
char c2;
};
U u;
auto ptr = new(u.c.buff +4) Vector{}; I wonder which objects in |
Every object which is nested within |
@languagelawyer So, |
See #5193 (comment) |
So, the conclusion to the above example in that comment is that:
Is this also your opinion? |
Perhaps we also need to allow other types for implicitly-defined assignment operators. struct Weird {
// no default ctor
Weird(int) {}
Weird(const Weird&) {} // non-trivial
Weird(Weird&&) {} // non-trivial
Weird& operator=(const Weird&) = default;
Weird& operator=(Weird&&) = default;
};
union Foo { // has deleted default/copy/move ctor, and eligible trivial copy/move assignment
char dummy;
Weird w;
};
int main()
{
Foo x{.w{42}}, y{.dummy{}};
y = x; // it seems that y.w should be made active
} In this case, |
@frederick-vs-ja Sure, I have said that
So, [class.copy.assign]p13 is reasonable to be changed if [class.copy.ctor] p15 has revisioned. |
When Anyway, this union shenanigans need a holistic review to decide how it interact with each other and the rest of the object model. |
[class.copy.ctor] p15 says
However, [class.union.general] p2 says
It doesn't make sense that we identify or create the corresponding object
o
for each object nested within the object. Since [basic.life] p1 says such an initialization will begin the lifetime of that object. If we copy each object into the destination, it will make no sense. Consider this exampleI think the copy initialization at
#1
just needs to create the object that corresponds toU::i
intou2
and copy the data fromu.i
. So, is the following phrase the intent of [class.copy.ctor] p15?The similar issue is also in [class.copy.assign]p13.
The text was updated successfully, but these errors were encountered: