On Fri, Aug 23, 2013 at 7:32 PM, Mike Stump <[email protected]> wrote:
> On Aug 22, 2013, at 7:16 PM, Gabriel Dos Reis <[email protected]>
> 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