Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Order of evaluation in new expression

8 views
Skip to first unread message

Hyman Rosen

unread,
Apr 20, 2005, 9:54:33 PM4/20/05
to
I've often commented here that I belive that C++ should
define strict left-to-right order of evaluation. For the
sake of argument, let's agree to this. I've come up with
a case where I don't really know what's best, namely in
new expressions. Suppose we have the following:

void *operator new[](unsigned, int);
int main() { int n = 0; new (++n) float[++n]; }

Strict left-to-right in source would result in calling
operator new[](2 * sizeof(float) + x, 1);

You could make an argument for evaluating the array size
expression first, since it becomes the first argument to
the function, resulting in
operator new[](1 * sizeof(float) + x, 2);

There's a similar but less ambiguous situation for

void *operator new(unsigned, int);
int main() { int n = 0; new (++n) float(++n); }

Here we don't need the initializer until after the allocation,
so it seems the only reasonable outcome is
operator new(1)
initialize new float to 2

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Llewelly

unread,
Apr 21, 2005, 4:54:55 AM4/21/05
to
Hyman Rosen <hyr...@mail.com> writes:

> I've often commented here that I belive that C++ should
> define strict left-to-right order of evaluation. For the
> sake of argument, let's agree to this. I've come up with
> a case where I don't really know what's best, namely in
> new expressions. Suppose we have the following:
>
> void *operator new[](unsigned, int);
> int main() { int n = 0; new (++n) float[++n]; }

I would suggest a compile time error is best, but the argument over
whether or not it's ok for the standard to replace undefined
behavior with a compile time error deserves a thread of its
own. :-)

>
> Strict left-to-right in source would result in calling
> operator new[](2 * sizeof(float) + x, 1);
>
> You could make an argument for evaluating the array size
> expression first, since it becomes the first argument to
> the function, resulting in
> operator new[](1 * sizeof(float) + x, 2);

Most (if not all) of us will use the form 'new (++n) float[++n]' much
more frequently than we will have to recall that equivalence. Many
C++ programmers are completely unfamiliar with the equivalence.

So I feel that following the apparent visual order (the first order)
is best, on the grounds that it results in the fewest surprises.

>
> There's a similar but less ambiguous situation for
>
> void *operator new(unsigned, int);
> int main() { int n = 0; new (++n) float(++n); }
>
> Here we don't need the initializer until after the allocation,
> so it seems the only reasonable outcome is
> operator new(1)
> initialize new float to 2

Agreed.

ka...@gabi-soft.fr

unread,
Apr 21, 2005, 5:09:10 AM4/21/05
to
Hyman Rosen wrote:
> I've often commented here that I belive that C++ should
> define strict left-to-right order of evaluation. For the
> sake of argument, let's agree to this. I've come up with
> a case where I don't really know what's best, namely in
> new expressions.

There is no "best" (even in the general case). All that is
important is that it is defined, one way or another, and that
the rules are simple and easy to understand.

> Suppose we have the following:

> void *operator new[](unsigned, int);
> int main() { int n = 0; new (++n) float[++n]; }

> Strict left-to-right in source would result in calling
> operator new[](2 * sizeof(float) + x, 1);

> You could make an argument for evaluating the array size
> expression first, since it becomes the first argument to
> the function, resulting in
> operator new[](1 * sizeof(float) + x, 2);

> There's a similar but less ambiguous situation for

> void *operator new(unsigned, int);
> int main() { int n = 0; new (++n) float(++n); }

> Here we don't need the initializer until after the allocation,
> so it seems the only reasonable outcome is
> operator new(1)
> initialize new float to 2

It's not a big thing, but IMHO, the simplest rule is simply left
to right. Textually, without worrying about anything else.
The KISS principal.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

0 new messages