Date: Sun, 26 Oct 2025 13:04:27 -0400
On Sun, Oct 26, 2025 at 11:04 AM organicoman <organicoman_at_[hidden]> wrote:
> On Fri, Oct 24, 2025 at 10:54 PM organicoman via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >>
> >> Given a container of capacity 8, but has 5 elements.
> >> Let copy assign to it a container of same capacity and full (8 elements)
> >> All current containers implementation mixe two operations,
> >> 5 copy assignment + 3 copy construction.
> >> The same for move assignment:
> >> 5 move assignment + 3 move construction.
> >>
> >> If the value_type of the container has some side effects for its move/copy assignment operators (like a log msg), that will be very confusing, and imposes on the user to get in the implementations details of the container.
>
> >Does it impose anything, though?
>
> Yes Jason, if for example the growth factor of the implementation is different, the side effects will be different.
... so what? Those side effects *should not* affect the correctness of
your code. And if you need direct control over the growth factor of a
vector to maintain specific performance, then you shouldn't leave it
up to your standard library implementation.
> >What implementation details does code
> *need to know* about this?
>
> Some examples would be, growth factor, ×2? ×1.5?....what optimization used for trivially copyable value_type... 'noexcept' aware code...etc
>
> >When would it actually *matter* to the
> user, and why?
>
> Local reasoning...
> - I expect copy assignment, then i see mixture of copy assignment/construction...why?
It is wrong for you to expect this. Copy assignment and copy
construction are functionally doing the same thing. It should not
matter to you which is happening, so your expectations are misplaced.
> - Test case implementation. If your only way is to test against a text string.
... test what "against a text string"?
> And other reasons not on top of my head right now.
>
> In my little research I'm doing right now, I found that move operations are missing something
>
> A move operation should allow to be tested against....
>
> vec.is_moved_from();
>
> Should yield 'true' or 'false'.
> Which is not the case in the current state of the language.
... why is this a question worth asking? If you have a vector, and you
don't know what state it's in, you shouldn't be calling functions that
depend on it having any particular state.
>Copy assignment and copy construction fundamentally should yield the
> same result: two objects with equal values. No >code should *care* if
> >this is accomplished by constructing a new >object or assigning into an
> >existing one; the result ought to be the same. >That's what "copy"
> >means, and if your code cares about the >difference, then I would
> >suggest that its idea of what "copy" means is >incorrect.
>
> >The same goes for movement, but even >moreso (and that's ignoring the
> >issue everyone else brought up about how >moving in containers ought to
> >work).
>
> >Your code can tell the difference. But I >submit that if it *cares*
> >about the difference in some meaningful >way, your code is wrong to do
> >so.
>
> Where am I going with all this?
> The overall idea is to keep a consistent behavior for what a container should do, let say, in the Algebraic sense i.e
> One action on the container means the same action on all of its elements.
> And if we need to rename well established things then let that be.
The behavior is very consistent. It is only inconsistent if you care
about details you shouldn't care about.
> For example, if you analyze what the literature conveys about what a moved-from object means, you will find something similar to the following:
> "A moved from abject is in undefined but valid state, and the only operations allowed are assignment or destruction"
Incorrect. A moved-from object is in a state defined by that move operation.
By default, types defined in the standard library are in a
"valid-but-unspecified" state after movement (though there are many
exceptions). Even in this case, the operations that are allowed on it
are not limited to "assignment or destruction". It can be any function
which does not require the object to have any particular
state, like `clear`.
> Given the above... then i can assume that :
>
> vec[idx] = val ; // where vec is a moved-from vector, and idx < vec.size() before move ops.
>
> Is a well defined operation...since i just assigned a value to a moved-from element of a moved-from container, as per the definition above.
There is a difference between assignment to an object and assignment
to something *inside* of that object. `vec = thing` is assignment to
`vec`. `vec[idx] = thing` is not assignment to `vec`. It is
specifically calling a member function (`operator[]`) and performing
assignment to the return value of that member function.
If you think those are the same thing, then that's your problem. A
container and its contents aren't the same, nor should they be.
`vec[idx]` requires `vec` to be in a particular state. Specifically,
`vec.begin() + idx` must be a valid iterator pointing to an object
within its lifetime. Moving from `vec` does not guarantee that `vec`
is left in such a state.
Nor should it.
> But in reality, that's an undefined behaviour.
>
> So what the literature describes as 'undefined but valid stat', is in itself unclear and bears many meanings.
> Which adds to burden of the C++ language, which is already full of those fuzzy constructs.
It's only unclear if you think that assignment to an object and
assignment to that object's contents are the same operation. You are
only confused by your own misunderstanding.
> > Apart from this explanation. As a free question, how can we tell the difference between dereferencing a pointer to an object within its lifetime, and the one not yet initialized.
>
> >You aren't supposed to be able to tell from within the code; that's on
> >you to pay attention to. That's why >dereferencing a point to an object
> >past its lifetime is UB instead of ill-formed. >You have the
> >responsibility to know what you're doing if >you're playing with raw
> >pointers.
>
> Yes i know Jason.
> This question was meant to trigger some brainstorming debate...unfortunately other people responding to this thread, give the sentiment that they are happy with the current state of the language, and any question that would trigger innovation is silly....that's Ok for me no problem at all.
I don't see how making everyone else's code worse (or out-right
breaking it) counts as "innovation".
> On Fri, Oct 24, 2025 at 10:54 PM organicoman via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >>
> >> Given a container of capacity 8, but has 5 elements.
> >> Let copy assign to it a container of same capacity and full (8 elements)
> >> All current containers implementation mixe two operations,
> >> 5 copy assignment + 3 copy construction.
> >> The same for move assignment:
> >> 5 move assignment + 3 move construction.
> >>
> >> If the value_type of the container has some side effects for its move/copy assignment operators (like a log msg), that will be very confusing, and imposes on the user to get in the implementations details of the container.
>
> >Does it impose anything, though?
>
> Yes Jason, if for example the growth factor of the implementation is different, the side effects will be different.
... so what? Those side effects *should not* affect the correctness of
your code. And if you need direct control over the growth factor of a
vector to maintain specific performance, then you shouldn't leave it
up to your standard library implementation.
> >What implementation details does code
> *need to know* about this?
>
> Some examples would be, growth factor, ×2? ×1.5?....what optimization used for trivially copyable value_type... 'noexcept' aware code...etc
>
> >When would it actually *matter* to the
> user, and why?
>
> Local reasoning...
> - I expect copy assignment, then i see mixture of copy assignment/construction...why?
It is wrong for you to expect this. Copy assignment and copy
construction are functionally doing the same thing. It should not
matter to you which is happening, so your expectations are misplaced.
> - Test case implementation. If your only way is to test against a text string.
... test what "against a text string"?
> And other reasons not on top of my head right now.
>
> In my little research I'm doing right now, I found that move operations are missing something
>
> A move operation should allow to be tested against....
>
> vec.is_moved_from();
>
> Should yield 'true' or 'false'.
> Which is not the case in the current state of the language.
... why is this a question worth asking? If you have a vector, and you
don't know what state it's in, you shouldn't be calling functions that
depend on it having any particular state.
>Copy assignment and copy construction fundamentally should yield the
> same result: two objects with equal values. No >code should *care* if
> >this is accomplished by constructing a new >object or assigning into an
> >existing one; the result ought to be the same. >That's what "copy"
> >means, and if your code cares about the >difference, then I would
> >suggest that its idea of what "copy" means is >incorrect.
>
> >The same goes for movement, but even >moreso (and that's ignoring the
> >issue everyone else brought up about how >moving in containers ought to
> >work).
>
> >Your code can tell the difference. But I >submit that if it *cares*
> >about the difference in some meaningful >way, your code is wrong to do
> >so.
>
> Where am I going with all this?
> The overall idea is to keep a consistent behavior for what a container should do, let say, in the Algebraic sense i.e
> One action on the container means the same action on all of its elements.
> And if we need to rename well established things then let that be.
The behavior is very consistent. It is only inconsistent if you care
about details you shouldn't care about.
> For example, if you analyze what the literature conveys about what a moved-from object means, you will find something similar to the following:
> "A moved from abject is in undefined but valid state, and the only operations allowed are assignment or destruction"
Incorrect. A moved-from object is in a state defined by that move operation.
By default, types defined in the standard library are in a
"valid-but-unspecified" state after movement (though there are many
exceptions). Even in this case, the operations that are allowed on it
are not limited to "assignment or destruction". It can be any function
which does not require the object to have any particular
state, like `clear`.
> Given the above... then i can assume that :
>
> vec[idx] = val ; // where vec is a moved-from vector, and idx < vec.size() before move ops.
>
> Is a well defined operation...since i just assigned a value to a moved-from element of a moved-from container, as per the definition above.
There is a difference between assignment to an object and assignment
to something *inside* of that object. `vec = thing` is assignment to
`vec`. `vec[idx] = thing` is not assignment to `vec`. It is
specifically calling a member function (`operator[]`) and performing
assignment to the return value of that member function.
If you think those are the same thing, then that's your problem. A
container and its contents aren't the same, nor should they be.
`vec[idx]` requires `vec` to be in a particular state. Specifically,
`vec.begin() + idx` must be a valid iterator pointing to an object
within its lifetime. Moving from `vec` does not guarantee that `vec`
is left in such a state.
Nor should it.
> But in reality, that's an undefined behaviour.
>
> So what the literature describes as 'undefined but valid stat', is in itself unclear and bears many meanings.
> Which adds to burden of the C++ language, which is already full of those fuzzy constructs.
It's only unclear if you think that assignment to an object and
assignment to that object's contents are the same operation. You are
only confused by your own misunderstanding.
> > Apart from this explanation. As a free question, how can we tell the difference between dereferencing a pointer to an object within its lifetime, and the one not yet initialized.
>
> >You aren't supposed to be able to tell from within the code; that's on
> >you to pay attention to. That's why >dereferencing a point to an object
> >past its lifetime is UB instead of ill-formed. >You have the
> >responsibility to know what you're doing if >you're playing with raw
> >pointers.
>
> Yes i know Jason.
> This question was meant to trigger some brainstorming debate...unfortunately other people responding to this thread, give the sentiment that they are happy with the current state of the language, and any question that would trigger innovation is silly....that's Ok for me no problem at all.
I don't see how making everyone else's code worse (or out-right
breaking it) counts as "innovation".
Received on 2025-10-26 17:04:39
