On Fri, Aug 23, 2013 at 7:32 PM, Mike Stump <mikest...@comcast.net> wrote: > On Aug 22, 2013, at 7:16 PM, Gabriel Dos Reis <g...@integrable-solutions.net> > wrote:
>> But even so, in light of this, I don't think you original assertion is >> definitive. > > Nothing is ever definitive. Now, if you want to say I quoted something > wrong, or that I am reading the standard wrong, or that it doesn't apply as I > think it does, feel free to point this out. I do view this as as a two way > street, despite the certainty I might profess. Ha! If you quoted the standard to back up your assertions, I would have been able to "feel free to point this out" :-) The thing is I am still trying to figure out what (1) what you would have liked; (2) what you believe the standards mandate, with appropriate quote; and (3) what you consider QoI. (3) would be a matter of GCC design choice discussion: for example, what we would like to guarantee under certain flags, etc. You need to separate those three things so we can make progress. >> >> Really? > >>> statement, or, is it merely changing the value? >> >> That is an assignment to an existing int storage. > >>> And what if we do a memcpy (ip, &j, sizeof (int)); >> >> Well, the case of 'memcpy' isn't defined by the standard > > Odd, in the c++98 standard memcpy was defined by the standard, as well as the > open code that memcpy would be. I find memcpy in [diff.library]. I can > quote all the requirements that makes the open code work as well. It is > defined. When I say "the case of 'memcpy' isn't defined", I was not saying that the function "memcpy" itself isn't defined by the standard. I was discussing its effect in the scope of this discussion, e.g. lifetime vs. assignment. That isn't defined in the standard. > > You can see evidence that we meant for it to work here: > > 2 For any complete POD object type T, whether or not the object holds a > valid value of type T, the underlying bytes (_intro.memory_) making up > the object can be copied into an array of char or unsigned char.36) If > the content of the array of char or unsigned char is copied back into > the object, the object shall subsequently hold its original value. > [Example: > #define N sizeof(T) > char buf[N]; > T obj; // obj initialized to its original value > memcpy(buf, &obj, N); // between these two calls to memcpy, > // obj might be modified > memcpy(&obj, buf, N); // at this point, each subobject of obj of > scalar type > // holds its original value > > thought, I view this as completely redundant with the standard and should > just be a note. From the base standard, in C99 is it defined in 7.24.4.2.3 > and I suspect remains largely unchanged from previous standards. > This does not say whether the effect of memcpy is assigment or copy construction. Which was the point I was making. >>> Is that reused, or merely changing the value. >> >> The current proposal is that it constructs an int value, therefore >> is moral equivalent of copy-constructor call. > > I'd be interested in the final resolution. You have a DR number for the > issue or a paper where they talk about the issues? This came out of a discussion of a larger issue on the SG12 mailing list. I do not have the paper number yet since it is to be part of the Chicago mailing list. >>> I think the most logical line of reasoning is that when the requirements of >>> [basic.lval] are met, the, this is a change of value of an object, not a >>> modification to it's lifetime. >> >> Why? > > Because if you end the lifetime of the original int, you destroy the semantic > that everyone knows for C. This cannot be done. But: (1) we are not talking about C (2) C does not have a notion of lifetime -- at least not in the sense of C++. So, whatever notion of semantics you think everyone knows of C is largely irrelevant. >>> So, in the case quoted, since the type of the accesses are both int, we >>> don't reuse the storage, since the requirements of [basic.lval] are met. >> >> Consider: >> >> struct S { >> S(int); >> ~S(); >> // … >> }; >> >> int main() { >> S s(8); >> >> new (&s) S(9); // #1 >> } >> >> Is #1 a reuse of storage to create a new object or assignment? > > Behaves as assignment, s exists post the new, til the closing }. What does not mean concretely? Note that the "// …" could have declared S::operator= to behave differently or be entirely deleted. >>> Indeed, the programmer expects that they can access i after *ip = j; and >>> that the _value_ that object, while changed from the original 1, will be 2 >>> just after the *ip = j; statement. >>> >>> Since we know that i must be 3 at the end, we then know what the wording, >>> reused, must mean, cause other meanings that could possibly make it work >>> for you in the case you are considering, would destroy this property of >>> pointers, and everyone knows the semantics of pointers, they are >>> undisputed. Or put another way, you cannot misread reused in this way. >> >> And why do you assert that I misread 'reused' in this way? > > See your email that I originally replied to. > > Let me quote it here: > >> If the user-supplied operator new returns &a, then it must >> also ensure that 'a' is not used anywhere else -- e.g. I you can't >> do lvalue-to-value conversion on 'a' to see what is written there. >> Because its storage has been reused. > > You said it was reused, this is wrong. You keep saying it is wrong without quoting the standards that is the basis for that. > You use that as backing to say that the lifetime of the original object ends, > this is wrong. You *assert* it is wrong. -- Gaby