--
Dave Abrahams
Boostpro Computing
http://boostpro.com
On Jul 18, 2008, at 7:30 AM, Daryle Walker
On Jul 18, 2008, at 6:57 AM, David Abrahams wrote:
on Fri Jul 18 2008, Daryle Walker
wrote: On Jul 18, 2008, at 5:07 AM, Daryle Walker wrote:
On Jul 17, 2008, at 10:32 PM, David Abrahams wrote:
[SNIP]
Then, if I understand you correctly, none of the built-in types are Assignable.
char* p; // p is unintialized char* q = p; // invalid
Yes, uninitialized is one of the valid states for a builtin type, i.e. part of the type's invariants.
Really, I was wondering about that (corner) case, especially since it can't be replicated (i.e. it's undefined to use such a state as a source). I'm thinking more about non-POD class types, which must have an initial state with the internal primitive objects initialized.
Well, I looked into it further. In C++ 2003, section 4.1 "Lvalue- to- rvalue conversion" [conv.lval], paragraph 1, an uninitialized object can only be used as an lvalue, converting it to a rvalue is undefined behavior.
Yes, that's what "// invalid" means.
This means that your program is illegitimate and we can't count it as a counter-example.
Huh? By that logic no counterexample is possible. Or am I missing something?
Yes, the OP was having a problem with a boost class (template) that is like std::valarray: you can only do assignments if the source and destination objects _already_ had the same layout.
I understand that
And my first response to this thread explained why this is problematic for our users,
I understand that too. My problem is with your implicit declaration that such types are not to be considered Assignable. That concept is supposed to be compatible with the builtins.
and so we shouldn't do this. In this setup, all objects are validly initialized; it's just there isn't a single assignment-compatibility class that all valid object states belong to. Note that you have to go out of your way to create a class like this.
Not really. It's pretty easy to end up with uninitialized members. But that's really beside the point.
It's a pain because the user who wants to use this class internally has either make sure all wrapping objects keep all sub-objects of this type within the same assignment-compatibility class or write a custom assignment routine. Said routine can be at most the basic guarantee if the resizing or copy steps may throw.
So? I don't see how that's related or why it's a problem
(A strong guarantee could be done if the type provides a swap that can cross assignment-compatibility classes.) An author-supplied full-assignment routine could take advantage of the internal implementation and add rollback.