On Thu, Aug 22, 2013 at 6:16 PM, Mike Stump <mikest...@comcast.net> wrote:
> On Aug 22, 2013, at 2:28 PM, Gabriel Dos Reis <g...@integrable-solutions.net> 
> wrote:
>> On Thu, Aug 22, 2013 at 4:14 PM, Mike Stump <mikest...@comcast.net> wrote:
>>> On Aug 22, 2013, at 9:45 AM, Gabriel Dos Reis 
>>> <g...@integrable-solutions.net> wrote:
>>>>> I.e. can I have something like
>>>>>
>>>>> int a;
>>>>> test()
>>>>> {
>>>>> int *b=new (int);
>>>>> }
>>>>>
>>>>> with custom implementation of new that returns &a?
>>>>
>>>> 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.
>>>
>>> This is wrong, in the c++97 standard there is no such limitation or 
>>> restriction.
>>
>> Please, elaborate.
>
> Sure, there is no wording that limits as you describe.  There is a limit for 
> polymorphic classes and classes with virtual bases (See [class.cdtor], but 
> that is due to the vtable pointer lifetime and vbase pointer (offset) 
> lifetime.  Essentially, you can't use viable pointers or do vbase conversions 
> before they are set, and they are only set at a particular time.  The 
> standard keeps it simple and expands to non-POD, but I'd argue that from a 
> QOI we should not make things that can work, not work.  See below on QOI 
> issues.

I think we must distinguish what is "wrong" according to the standards
we are implementing from what is "wrong" from a QoI point of view.

My reasoning (for C++98, but the same is true for C++11) is based
on 3.8/1:
   […]
   The lifetime of an object of type T ends when:
    -- if T is a class type with a non-trivial destructor (12.4),
       the destructor call starts, or
    --  the storage which the object occupies is reused or released.

Doing a placement-new on the storage occupied by 'a' is reusing
its storage, therefore ending its lifetime.

-- Gaby

>
> I can't quote it, since the limitation doesn't exist.  I can quote the 
> language that allows & on an object, that you can then cast this to be of a 
> different type, and then dereference and use that type, if you want.  I can 
> quote the object lifetime rules, that describe when it comes into existence, 
> and when it goes away.  But, none of these are terribly surprising.  If you 
> want to narrow done what part of the language you're interested in, I can 
> quote just that part.
>
> int a;
>
> a exists before the program runs, and exists till after the program is 
> finished running (See [basic.stc.static]).  That's the lifetime of it.  
> During it's lifetime, you can use it in the ways the standard lets you.  For 
> example, ++a;.  In the below:
>
> void foo() {
>         char *cp = &a;
>
>         [ … ]
> }
>
> cp's lifetime is from the declaration of it, til the }.  The character object 
> that cp points to has a lifetime.  It's lifetime is from before the program 
> runs, til after the program finishes.  (See [basic.life])  It can be used any 
> way that a lvalue character can be used.  Since you can't use cp before it's 
> lifetime, to use this character object outside of the lifetime of cp, you'd 
> need another reference to it beyond just cp.  Again, this isn't suppose to be 
> surprising.
>
> Now, we do have wording like:
>
> 15If  a program attempts to access the stored value of an object through
>   an lvalue of other than one of the following  types  the  behavior  is
>   undefined48):
>
> and we do have latitude to do things that uses that as a basis, but, once one 
> ensures locking, say with atomics or volatile, to ensure the variable hits 
> memory, I will argue that we can't make as much use of that from a quality of 
> implementation viewpoint, despite the standard wording.  Now, even without 
> volatile and locking, from a quality of implementation point of view, we 
> don't actually want to make full use of undefined.  QOI still forces us to do 
> the right thing.  undefined means, we get to kill the user.  QOI means, even 
> though we can, we refrain from it, cause if we did, they would not like us.
>
> For the case of a int, and a placement new on that int, of an int.  The 
> behavior is mandated by the standard to work.  For a allocation function, 
> they are free to play games with persistence (or unexec a la emacs), with 
> allocated objects and this too has to work.  This means they can alias, and 
> the standard says they can write this code and the standard mandates that it 
> works.
>
> Now, the user can use:
>
> @item malloc
> @cindex @code{malloc} attribute
> The @code{malloc} attribute is used to tell the compiler that a function
> may be treated as if any non-@code{NULL} pointer it returns cannot
> alias any other pointer valid when the function returns and that the memory
> has undefined content.
> This often improves optimization.
> Standard functions with this property include @code{malloc} and
> @code{calloc}.  @code{realloc}-like functions do not have this
> property as the memory pointed to does not have undefined content.
>
> on their allocation functions, if they want.  And if they do, than what it 
> says is true, by definition, but not by standard.  When this isn't true, the 
> user will refrain from using this attribute.

Reply via email to