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

Reply via email to