This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ patch] Set attributes for C++ runtime library calls

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]