This is the mail archive of the gcc@gcc.gnu.org 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]

Re: GCC's statement expression extension


> To: per@bothner.com
> From: Mark Mitchell <mark@codesourcery.com>
> Date: Sat, 29 Jul 2000 10:42:58 -0700

> That seems like the obvious right answer.  It just doesn't work very
> well for:

>   X x;
>   X f();

>   x = ({ f(); });

It seems like it does to me.  There is a preexisting references extend
the life of temporaries rule already in the C++ standard that I think
covers one sensible way to treat this case.  With that, it make
perfect sense to me.  It is true, that we have to realize that rule
`fits' in this situation, I see that as obvious.

> Oops.  The return value of f() got destroyed before we got a chance to
> copy it.  (There are more complex examples with similar problems,
> including binding things to references, which cause lifetime
> extensions in C++.)

It seems like the same issue to me.

> To: Mark Mitchell <mark@codesourcery.com>
> From: Alexandre Oliva <aoliva@redhat.com>
> Date: 29 Jul 2000 15:47:26 -0300

> I see.  We'd have to have copied it to some temporary that would
> hold the result of the statement expression before calling its
> destructor.

A copy ctor to another temporary is another way to think about this.
This also fits, though, at first blush I think less well than
extending the lifetime.  Though, there might be technical reasons that
cause one to want to mandate a copy, and then permit the compiler to
get it of it, if it can.

> To: Mark Mitchell <mark@codesourcery.com>
> From: Alexandre Oliva <aoliva@redhat.com>
> Date: 29 Jul 2000 16:29:53 -0300

> How about, for a start, mandating that the result of a statement
> expression be a POD object?  This would get us rid of the problem of
> handling destructors

I don't see a problem handling destructors.  I think the inside temps
expire at their full expression within the statements, and the object
that escapes from the expression in the expression statement has its
lifetime extended.  Simple, easy, consistent, predictable and in the
spirit of the standard.

> To: aoliva@redhat.com
> From: Mark Mitchell <mark@codesourcery.com>
> Date: Sat, 29 Jul 2000 12:52:41 -0700

> There are other problems too:

>   #define foo(X) ({ /* some code */ f(X); /* some more code */ })

> Now, suppose that X is an expression that creates temporaries, and
> that `foo' is a standard library function.  (I've seen this with the
> glibc headers by the way.  Some of them do something like:

>   #define foo(x) ({ int i = x; ... }) 

> which has this form.)

> Then, temporaries involved in the X expression are destroyed at the
> end of the statement-expression, which is earlier than the language
> says they should be.  We break conformant programs in this way.

I find the argument where a person misuses #defines and doesn't meet
the requirements of the standard and breaks conformant code this way,
while implementing parts of the standard, to be not very convincing.
They can misuse a good number of features to break user code already.

> That's another reason why this construct has such difficult semantics
> in C++.

I don't see it this way.

> To: Mark Mitchell <mark@codesourcery.com>
> From: Alexandre Oliva <aoliva@redhat.com>
> Date: 29 Jul 2000 18:07:12 -0300

> On Jul 29, 2000, Mark Mitchell <mark@codesourcery.com> wrote:

> > There's really no right answer -- the other answer is to wait
> > until the end of the enclosing full expression.

> It appears to me that this would solve all of the problems you've
> listed so far, and it seems reasonably sound to me.

I don't think it is reasonable.  The words in the standard say that
certainly by the time the statement containing an expression ends, the
temps are gone.  You cannot violate this rule without a very good
reason.

> To: aoliva@redhat.com
> From: Mark Mitchell <mark@codesourcery.com>
> Date: Sun, 30 Jul 2000 10:06:06 -0700

> You can define the semantics any weird way you want, and given N
> problems you can probably come up with a semantics that solves all N
> of them.  What I don't think possible, unfortunately, is come up
> with semantics that are consistent, in the spirit of C++, and easy
> for users to understand, and will solve the N+1st problem.

I disagree.  What problems remain?

> It adds no additional power, it provides no additional cleanliness,
> affords no portability.  On the other hand, it has dubious
> semantics, at best, and is difficult to implement (especially when
> you consider using these things in default arguments.

What are the issues you don't like with regard to default arguments?

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