On Aug 22, 2013, at 2:28 PM, Gabriel Dos Reis <[email protected]>
wrote:
> On Thu, Aug 22, 2013 at 4:14 PM, Mike Stump <[email protected]> wrote:
>> On Aug 22, 2013, at 9:45 AM, Gabriel Dos Reis
>> <[email protected]> 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 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.