Topic: 5.2.2/8 unspecified evluation oder?


Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sun, 7 Aug 2005 19:49:35 GMT
Raw View
In article <IKtBL6.1sI2@beaver.cs.washington.edu>, "Andrei Alexandrescu
(See Website For Email)" <SeeWebsiteForEmail@moderncppdesign.com> writes
>So today's machines already enjoy the freedom of evaluating code
>out-of-order, but in a safe and predictable manner. They do it, and
>they do it with predictable visible semantics. Leaving a dangerous hole
>in the language when the benefit is safely reaped anyway -- that's just
>longer justified.

I would be much more convinced if a major compiler (preferably G++ or
Comeau) gave the guarantee as an extension because I always feel very
insecure about making changes based on belief on what can be achieved.

I normally argue the other side of this issue but I want to see the
proponents produce stronger arguments for it.

BTW, one thing that does concern me is that too many people confuse
order of evaluation issues with problems of side effects and sequence
points. Guaranteeing order of evaluation does not solve the side-effects
issue.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bop@gmb.dk ("Bo Persson")
Date: Thu, 4 Aug 2005 16:11:03 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> skrev i meddelandet
news:qTgIe.6018$%a2.5091@trndny03...
> kuyper@wizard.net wrote:
>> The constructs in C++ that guarantee a specific order of operation
>> are few;
>
> Really? Let's count some.
>
> 1) Sequence of statements:
>    f(); g(); h();
>
> 2) Comma operator (but not if user-defined!):
>    f(), g(), h();
>
> 3) Initializers:
>    int a = f(), b = g(), c = h();
>    int a[] = { f(), g(), h() };
>
> 4) Constructors:
>    struct s { int a, b, c; s() : a(f()), b(g()), c(h()) { } };

But here the order is not defined by the initializing expressions, but
by the members.

struct s { int c, b, a; s() : a(f()), b(g()), c(h()) { } };

is suddenly evaluated right to left.

>
> 5) Function arguments:
>    p = strchr(++p, '.');
>
> 6) Short-circuited boolean operators (but not if user-defined!):
>    f() && g() || h();
>
> 7) ternary operator:
>    f() ? g() : h();
>
> 8) Control constructs:
>    if (f()) g();
>    while (f()) g();
>    do f(); while(g());
>
> 9) Combinations of user-defined operators (but not built-in ones!):
>    struct x { x &operator++(int) { return *this; }
>               x &operator=(const x &) { return *this; } };
>    x a;
>    a++ = a;
>
> And I've probably missed a few. In fact, the only place where an
> explicit order *isn't* defined is among the subexpressions of some
> forms of full expressions. Note the especially pernicious cases of
> 2, 6, and 9, where the validity of an expression may depend on
> whether the operators are intrinsic or uder-defined. Now imagine
> writing a template using these operators.

Why don't we just remove the comma operator and user defined boolean
operators? That would solve these problems.

>
>> it's easy enough to adopt a programming style where the tricky
>> parts
> > of sequence points don't cause problems
>
> Is it? With the language as it currently is, adopting this style
> means adding extra variable or reference declarations for
> intermediate
> expressions.

How often do you really write function calls where the order of
evaluation actually matters? In my case it is hardly ever.

Should it happen, I will be happy to put the offending code in a
statement by itself, preceding the function call. No big deal.

> With template metaprogramming so popular, it's possible
> that the types for those declarations aren't readily available, or
> are
> hideously long and complicated.
>
>>>It would be one thing if the language feature contributed
>>>something useful, but it doesn't.
>>
>> That's precisely the point of our disagreement.
>
> There is essentially no use in trying to convince some people of
> this,
> because they can always pull out the example of the emebedded DPD-IX
> processor which drives their three-slice toaster, and which runs
> five
> times as fast if procedure arguments are evaluated from the outside
> in.

It will of course be *extremely* difficult for the standards committee
to reach an agreement on a language that cannot be effectively
implemented by all the committee members. Those who make a living
producing tools for the DPD-IX processor are likely to vote against
this change.

>
> If they can't see that having gratuitously unspecified constructs in
> something intended to drive the behavior of a machine makes
> absolutely
> no sense, there's nothing I can really do about it, except to keep
> plugging away and hope that their point of view becomes so in the
> minority that it will be ignored.

We are not arguing whether we should add random unspecified behaviour,
but whether it is worth the trouble of changing the language to solve
a problem that hardly ever happens, at least not to me.


You want a defined order of evaluation for parameters, I prefer the
fastest possible code. If I occationally have to write an extra
statement or two, that is well worth the trouble.



Bo Persson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: Thu, 4 Aug 2005 18:25:00 CST
Raw View
In article <E1E0ihF-0004i4-00@chx400.switch.ch>, Hyman Rosen
<hyrosen@mail.com> writes
>Andrei Alexandrescu (See Website for Email) wrote:
>> Speaking of which, are you planning to embark on a proposal?
>
>I was afraid someone would finally ask me that :-)
>I haven't written anything up yet. I hope to do it
>one day, but no promise as to when.

Than it will not change before 2019.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "P.J. Plauger" <pjp@dinkumware.com>
Date: 5 Aug 2005 23:00:18 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:20050803191201.15B621140B2@mscan6.ucar.edu...

> kuyper@wizard.net wrote:
> > "this is a language without training wheels - it's not for you"
>
> This is what one says about features which are powerful but easy
> to misuse. It is not what one says about misfeatures which are
> useless but easy to stumble over. You want to have a chainsaw
> without a guard, fine, but there's no reason for the handle to
> have sharp bits that slice up your fingers.
>
> > improved education or a change of profession is the solution
>
> This is a user-interface problem. The solution to such problems
> is not to insult the users but to fix the source of confusion.
> It would be one thing if the language feature contributed
> something useful, but it doesn't. Converting underspecified
> behavior to fully specified behavior is only good.

I responded to this once, but my response seems to have gotten
lost somewhere in the moderation process (as sometimes happens
to me). It is *not* true that fully specifying behavior is
"only good". The users are happy until they're told that some
optimization they want is not permissible. The C committee
very intentionally left wiggle room for implementers in a
number of places. And architectures invented *since the C
Standard froze nearly 20 years ago* have benefited from this
wiggle room.

Be careful what you wish for.

>                                                    If a handful
> of compiler developers are put out by this, that's a very small
> price to pay.

And please don't make compiler writers the bad guys in this little
drama. It's not that they're lazy, but that they're torn in
multiple directions. They need whatever slack they can get to
make users happy.

>              It's nowhere near the cost of implementing the
> many other novelties that are upcoming. If you can make every
> compiler vendor implement a new kind of reference syntax you
> can make them do this.

Yep, just like you can make 'em implement export, and replace
all their old C headers, and...

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bop@gmb.dk ("Bo Persson")
Date: Sat, 30 Jul 2005 19:35:20 GMT
Raw View
"Martin Bonner" <martinfrompi@yahoo.co.uk> skrev i meddelandet
news:1122649512.879866.38000@g44g2000cwa.googlegroups.com...
>
> Marc Schoolderman wrote:
>> void f(const foo& obj)
>> {
>>      std::cout << obj.f() << obj.f() << obj.f() << std::endl;
>> }
>>
>> is perfectly okay. If obj.f() would modify the observable state of
>> the
>> object, this would either be caught at compiletime, or be indicative
>> of
>> problems in the class that will probably crop up elsewhere too.
>
> Unless foo::f is defined as:
>
> int foo::f()
> {
>   static int counter = 0;
>   return ++counter;
> }
>
> . or realistically, if f does not alter the object it is called on,
> but DOES alter something in the wider world.
>

But it still boils down to the same question:

Why should we require that there *always* is a defined order? Just
because we might occationally need it, and are too lazy to spell it out
when it does matter?

const int first = obj.f();
const int second = obj.f();
const int third = obj.f();

std::cout << first << second << third << std::endl;


When you need expressions evaluated in a specific order, just write them
in that order. When it doesn't matter, it doesn't matter. Problem
solved!


Hardly worth a language change to avoid this "workaround"!


Bo Persson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bop@gmb.dk ("Bo Persson")
Date: Mon, 1 Aug 2005 17:22:54 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> skrev i meddelandet
news:0RfHe.2500$%a2.1721@trndny03...
> You are assuming that it is perfectly obvious that
>      f(); f(); f();
> should result in a completely defined order while
>      p(f(), f(), f());
> equally obviously must have an unspecified order, and that it is
> laziness
> to expect the latter to operate like the former. But that is not
> obvious
> at all. It's merely a historical accident that things currently work
> like
> this. And the reason we should require that there *always* is a
> defined
> order is that programming languages are the means by which we instruct
> computers what to do, and permitting ambiguity in the language is
> useless
> and can only lead to error.

Or it could lead to better performance, but not tying one of the
implementor's hands to her back.

The problem is not so much for the silly p(f(), f(), f()), but for
p(f(), g(), h()), where it might be expensive to store some of the
intermediate results, while calculating the others. If we leave it up to
the compiler implementor to choose, perhaps differently for each call,
perhaps interleaving the parameter evaluations, at least the code will
not be any slower than it is now.

If we specify a certain order, just becase some of us belive that it
will sometimes be handy, there is certainly a risk that my code will run
slower, even when I don't see a need for a specific order. That is in
clear violation of the "you don't pay for what you don't use"-principle.

I would also rather see the compiler vendors working on their export
implementations, rather that reviewing their optimizers for very
possible violations of the now non-existant left-to-right parameter
evaluation order. The compiler I use the most, seems to prefer
right-to-left evaluation...


Bo Persson




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 1 Aug 2005 23:23:29 GMT
Raw View
In article <200508011747.j71HlbuC069360@horus.isnic.is>, Hyman Rosen
<hyrosen@mail.com> writes
>Bo Persson wrote:
>> The problem is not so much for the silly p(f(), f(), f()), but for
>>p(f(), g(), h()), where it might be expensive to store some of the
>>intermediate results, while calculating the others.
>
>There are no intermediate results, only function parameters being
>initialized. Assuming an architecture that doesn't pass them in
>registers anyway, it is possibly the difference between
>    call h; push $r; call g; push $r; call f; push $r; call p;
>and
>    sub 12, $sp;
>    call f; mov $r 8($sp);
>    call g; mov $r 4($sp);
>    call h; mov $r 0($sp);
>    call p;

I cannot follow your logic. What on earth causes the assumption that
f(), g() and h() return small objects. And what about optimising
register/cache usage?


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Bo Persson" <bop@gmb.dk>
Date: 2 Aug 2005 16:00:06 GMT
Raw View
""Andrei Alexandrescu (See Website For Email)""
<SeeWebsiteForEmail@moderncppdesign.com> skrev i meddelandet
news:IKJyCD.1Cz2@beaver.cs.washington.edu...
> Hyman Rosen wrote:
>> You are assuming that it is perfectly obvious that
>>      f(); f(); f();
>> should result in a completely defined order while
>>      p(f(), f(), f());
>> equally obviously must have an unspecified order, and that it is
>> laziness
>> to expect the latter to operate like the former.
>
> And for that matter (and to make the dichotomy more visible): Why
> should
>
> f(), f(), f();
>
> have a defined order, while
>
> p(f(), f(), f());
>
> shouldn't?

Who says that a token should always have the same effect, disregarding
the context?

The token separating function parameters sure looks a lot like the comma
operator, but it is not. So why should it have the same effect?

The first expression evaluates all three f()s, but only returns the
result of one of them. To be totally consistent, only one of the f()
return values should be passed to p(). Or what?

This is exactly what happens if you write

q[f(), f(), f()];

Here you evaluate the three f()s in a defined order, then only pass the
last result to q[].


Why does

p(f(), f(), f());

behave differently? Because it is different!



I oppose this just because it is a big change to the language, with very
little benefit. We already have the easy "workaround" of explicitly
specifying the order, by just writing it out as separate expressions.



Bo Persson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]