Topic: -1?Q? 5.2.2/8 unspecified evluation od
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 9 Aug 2005 01:16:32 GMT Raw View
Francis Glassborow wrote:
> 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.
I'm curious why you think so. Certainly when I write anything
about fixing order of evaluation issues, I mean to include side
effect completion as well. Have you seen people writing about
fixing order of evaluation issues without their meaning to
clear up side effects as well? Furthermore, without side effects,
what meaning can be ascribed to order of evaluation at all?
---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: 3 Aug 2005 19:20:06 GMT Raw View
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. If a handful
of compiler developers are put out by this, that's a very small
price to pay. 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.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 4 Aug 2005 05:05:41 GMT Raw View
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()) { } };
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.
> 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. 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.
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.
---
[ 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: seewebsiteforemail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 4 Aug 2005 16:11:56 GMT Raw View
Hyman Rosen wrote:
> 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()) { } };
>
> 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;
Heh, heh, heh. After having read Mr. Kuyper's post, I was like "said
what???" and felt compelled to produce a similar list, just to see the
one above a minute later. :o)
> Is it? With the language as it currently is, adopting this style
> means adding extra variable or reference declarations for intermediate
> expressions. With template metaprogramming so popular, it's possible
> that the types for those declarations aren't readily available, or are
> hideously long and complicated.
And then again, worst of all, the manifestation of forgetting to use
the more verbose style (which I agree it seldom improves readability)
is not hard errors; it's soft errors and nonportable behavior that
"works" by sheer luck on some machines and yields hard-to-track
problems on others.
> 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.
Speaking of which, are you planning to embark on a proposal?
Andrei
---
[ 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: caj@cs.york.ac.uk (chris jefferson)
Date: Thu, 4 Aug 2005 16:10:51 GMT Raw View
kuyper@wizard.net wrote:
> Hyman Rosen wrote:
>
>>kuyper@wizard.net wrote:
>>
>>>Yes, there are cases where even experts disagree about what ordering
>>>requirements the standard imposes.
>>
>>No, that's *not* what I'm saying. Experts don't disagree about what
>>the standard requires, they just make mistakes. We see that here,
>>over and over again.
>
>
> Yes, they sometimes make mistakes - which result in disagreements.
> There are also disagreements that arise not because of any mistakes
> that people have made, but because people adopted multiple different
> mutually incompatible interpretations of unclear wording in the
> standard, which are all arguably compatible with the actual wording.
>
>
>>>The rule is simple: avoid the tricky cases.
>>
>>Really? So everyone will realize that calling 'f(auto_ptr, auto_ptr)'
>>with 'f(new, new)' is a tricky case and avoid it?
>
>
> It's certainly something I'd never have tried.
>
>
>>... And everyone will
>>realize that doing 'cout << Start() << Middle() << Finish()' is a
>>tricky case and avoid it?
>
>
> No, of course not . Just like not everyone will realize that
>
> a = b+c - d+e;
>
> isn't equivalent to
>
> a = (b+c)-(d+e);
>
> I don't think we should cater to the limitations of the least competent
> users of the language. At some point we should tell them: "this is a
> language without training wheels - it's not for you". There are
> languages more suitable than C++ for such people, though I'd expect
> them to have a certain amount of trouble even when using the most
> user-friendly of languages.
>
I do quite a lot of programming in quite a lot of languages, and was
recently caught by the non-ordering of function arguments.
I often program in pure functional languages. There you often don't get
a well-defined order of execution, but on the other hand, it doesn't
matter as your functions don't have side effects.
While I probably haven't thought through all the consequences, If I was
in charge of designing C++, I would want a policy that a correct program
produced identical output on every compiler (well, modulo things like
types changing size), so I'd also fix the execution order of all the
operators as well. It disturbs me that one day, at a slightly changed
optimisation level, or using a new compiler, my program could change
symantics.
I'm a strong believer in unit tests, I usually have more tests than
code, and it makes me confident that my code is doing exactly what I
want it to do. However, there is no way for me to test for this kind of
thing, other than to see if one day some tester tells me on some obscure
platform or compiler setting suddenly large bunches of tests start failing.
> I agree; that's a problem; improved education or a change of profession
> is the solution.
Can you honestly say you've never been caught by some random part of the
C++ standard? This one I consider espically bad because your code will
compile and run fine until one day some compiler decides to rearrange
the order.
Chris
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 4 Aug 2005 17:06:52 GMT Raw View
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.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 4 Aug 2005 17:08:01 GMT Raw View
Bo Persson wrote:
> But here the order is not defined by the
> initializing expressions, but by the members.
But it is defined. And vitually every compiler will
warn you if you have the initializers out of order.
> Why don't we just remove the comma operator and user defined boolean
> operators? That would solve these problems.
Because these aren't problems. The problem lies in the
unspecified parts, not the specified ones.
> How often do you really write function calls where the order of
> evaluation actually matters? In my case it is hardly ever.
I believe the answer is "more times than you think", which is
the problem.
> Should it happen, I will be happy to put the offending code in a
> statement by itself, preceding the function call. No big deal.
As I have repeatedly stated, the problem is when you don't
realize that there's a dependency because the compiler is
doing it in a friendly order, and then something in the build
environment changes and so does the order, leading to mysterious
and hard to trace problems.
> 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.
It can always be effectively implemented, because the compiler already
has to deal with 'auto &a = f(), &b = g(), &c = h(); p(a,b,c);'.
> Those who make a living producing tools for the DPD-IX processor are
> likely to vote against this change.
Unanimity is desirable, but I don't think it's mandatory.
> We are not arguing whether we should add random unspecified behaviour,
No, we are arguing about *removing* 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.
Of course it happens. How many postings about sequence points (or clear
lack of knowledge about them) show up just on these newsgroups.
> 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.
I want a well-defined programming language whose constructs have
fixed meaning regardless of build environment. I believe that trumps
speed (although I continue to deny that speed would be affected).
---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: Thu, 4 Aug 2005 12:50:09 CST Raw View
msalters wrote:
> Hyman Rosen schreef:
>>5) Function arguments:
>> p = strchr(++p, '.');
>
> You mean evaluation of all parameters before execution, I guess?
Yes. This is an expression where p is modified twice,
but it is still well defined.
---
[ 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: "Andrei Alexandrescu (See Website for Email)" <seewebsiteforemail@moderncppdesign.com>
Date: Thu, 4 Aug 2005 14:00:40 CST Raw View
Hyman Rosen wrote:
> 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.
It would be a far better expenditure of your efforts than fighting a
vocal minority that won't let go. I would be glad to review your
proposal, so please let me know. I encourage others to help as well.
Time has come to extract that weed.
Andrei
---
[ 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: "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@moderncppdesign.com>
Date: 5 Aug 2005 18:00:42 GMT Raw View
Francis Glassborow wrote:
> 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.
"Better late than never."
Andrei
---
[ 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: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website For Email)")
Date: Sat, 6 Aug 2005 22:42:38 GMT Raw View
P.J. Plauger wrote:
> "Hyman Rosen" <hyrosen@mail.com> wrote in message
>>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.
That is true. I think, however, that the reasons for unspecified
evaluation order have largely disappeared. The generated code will be as
good even if left-to-right evaluation is required. Most of the time, the
order doesn't matter anyway, but 35 years ago, it was deemed
unproductive to have the compiler prove that, so they put the burden on
the programmer.
Today's compilers and processors (!) routinely scavenge code for
reorderings that can increase instruction-level parallelism, and can
most of the time prove statically (compilers) or dynamically
(processors, see Tomasulo's seminal algorithm and its many offspring)
which operations don't depend on the others, and reorder them to best
exploit hardware resources.
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 no
longer justified.
Andrei
---
[ 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: Marc Schoolderman <squell@alumina.nl>
Date: 30 Jul 2005 20:50:02 GMT Raw View
Martin Bonner wrote:
>>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:
<snip>
I don't think a member function should be 'const' solely because it
doesn't touch immutable non-static members.
> or realistically, if f does not alter the object it is called on,
> but DOES alter something in the wider world.
I can only imagine this for function objects. But then you can still
distinguish 'function-objects' and 'procedure-objects'.
In any case, I believe expressions should be agnostic to evaluation
order, or they will be harder to understand, change, and prove correct.
Functional programming languages try to teach this as well.
In extreme contrast, I read that C# has its evaluation order dependent
on operator precedence. If any one cares for that, just glance at this
discussion on MSDN; compare the C++ answer.
http://blogs.msdn.com/ericgu/archive/2004/04/19/116265.aspx
~Marc.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 1 Aug 2005 05:00:27 GMT Raw View
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.
---
[ 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: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website For Email)")
Date: Mon, 1 Aug 2005 22:04:31 GMT Raw View
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?
> 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.
I entirely agree. To partly address the efficiency argument, let me add
that today's compilers can still obey sequential evaluation of function
arguments while often reordering operations (to increase
instruction-level parallelism) as long as they can prove there are no
visible dependencies.
Andrei
---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: 1 Aug 2005 22:10:10 GMT Raw View
kuyper@wizard.net wrote:
> It's not useless, which is why it's not an historical accident. You
> might argue that it's not useful enough to justify the deliberate
> decision to leave the order unspecified; you might even be right, but
> you haven't successfully argued that case yet.
I will never succeed in arguing my case, because there will always
be people who insist that there is some architecture somewhere that
will benefit by arbitrary execution order, and that therefore this
permissiveness must continue. The only way to proceed is to ride
roughshod over those people and push through the rules regardless.
> the current language contains all of the features you
> need to force a particular order of evaluation.
The current language contains all you need to make a total hash of
your program because of all the little dumb gotchas that show up
everywhere, and can only be avoided by reading every expert-level
C++ book you can find. All those features that you can use to force
a particular order are useless if you don't realize that you need to
use them to begin with. How many people realized that it was unsafe
to call 'f(auto_ptr, auto_ptr)' as 'f(new, new)'? How many people
realize that now?
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 1 Aug 2005 22:05:03 GMT Raw View
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;
Now, maybe that's significantly slower. But that assumes nearly
no time taken by the calls themselves, nor does it take cognizance
of the modern CPUs which prefetch addresses, execute speculatively,
and have extensive caches. In fact, the Pentium has to take special
pains to make the push instruction efficient, because normally using
a register as an address immediately after modifying it causes a
pipeline stall.
> If we specify a certain order, just becase some of us belive that it
> will sometimes be handy
No, the handiness is just a convenient side effect of the real reason
we must specify the order, which is that no one understands the current
rules or gets them right, when they even realize that there is something
to worry about. And that goes for experts and novices alike, as we have
seen over and over again in this newsgroup.
---
[ 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: Marc Schoolderman <squell@alumina.nl>
Date: 2 Aug 2005 03:40:02 GMT Raw View
Hyman Rosen wrote:
I am trying to keep this focussed on C++, but this technical argument
necessitates a rebuttal.
> Now, maybe that's significantly slower. But that assumes nearly
> no time taken by the calls themselves, nor does it take cognizance
> of the modern CPUs which prefetch addresses, execute speculatively,
> and have extensive caches.
Could you please clarify how this applies in this context? I have read
and experimented quite a bit on this subject, and it's not obvious to me
at all. Speculation means helping code with branches, while prefetching
increases memory bandwidth in loops. Neither of this has anything to do
with instruction level parallelism, which is what evaluation order
interacts with.
Second, the bit about extensive caches is false. Processor speed has
gone up the ladder so hard, instruction caches have had to remain very
small to be able to provide low latency. My old rusty 486 clone has 32kb
of Level 1 cache, which is the same amount a modern Itanium2 sports.
> In fact, the Pentium has to take special
> pains to make the push instruction efficient, because normally using
> a register as an address immediately after modifying it causes a
> pipeline stall.
It also had to take pains to pair a "push", since normally two
instructions that write to the same cache bank couldn't be paired.
The upshot of all this was that pushing on the P5 was preferable to
equivalent code with movs, which doesn't strengthen your argument.
But, this architecture has been phazed out for years.
> > If we specify a certain order, just becase some of us belive that it
> > will sometimes be handy
> No, the handiness is just a convenient side effect of the real reason
> we must specify the order, which is that no one understands the current
> rules or gets them right
In that case, what is necessary is a clarification of what constitutes a
violation of the present rules.
~Marc.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 2 Aug 2005 05:07:58 GMT Raw View
Francis Glassborow wrote:
> I cannot follow your logic. What on earth causes the assumption that
> f(), g() and h() return small objects.
I cannot follow your logic. How does the size of the returned object
materially affect my example? If anything, since returning large
objects is often done by passing a pointer to the result location to
the function, it's more likely that in such a case the compiler will
need to reserve stack space for the parameter ahead of time, making
execution order completely irrelevant to the appearance of the
generated code.
> And what about optimising register/cache usage?
Yes, what about it? How do the two sequences differ?
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 2 Aug 2005 05:30:47 GMT Raw View
Marc Schoolderman wrote:
> In that case, what is necessary is a clarification of what constitutes a
> violation of the present rules.
The present rules are deadwood. They don't need to be clarified,
they need to be cleared. The problem is that virtually identical
syntax has wildly different semantics. No amount of clarification
can deal with that problem, because it is impossible to distinguish
the different cases when they are encountered. The only solution is
to make them behave uniformly.
This is one case where Java got it unquestionably right.
---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: Tue, 2 Aug 2005 11:49:42 CST Raw View
kuyper@wizard.net wrote:
> Yes, there are cases where even experts disagree about what ordering
> requirements the standard imposes.
No, that's *not* what I'm saying. Experts don't disagree about what
the standard requires, they just make mistakes. We see that here,
over and over again.
> The rule is simple: avoid the tricky cases.
Really? So everyone will realize that calling 'f(auto_ptr, auto_ptr)'
with 'f(new, new)' is a tricky case and avoid it? And everyone will
realize that doing 'cout << Start() << Middle() << Finish()' is a
tricky case and avoid it?
> If you're not sure whether the standard requires that one expression
> be evaluated before another, put them in seperate statements to ensure
> that they are evaluated in the required order.
As I have said, the problem isn't when you're not sure, the problem
is when you don't even realize that there's a question.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 2 Aug 2005 18:24:19 GMT Raw View
Bo Persson wrote:
> Who says that a token should always have the same effect,
> disregarding the context?
Elementary principles of user-interface design?
> 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?
Because in every context it's a sequencing operator.
It tells people 'first this, then that'.
> 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?
The comma operator evolved from the initial part of the 'for'
statement. That traditional form is 'i = 1, j = 2, k = 3' and
there each result is in fact used.
> 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.
It is a moderate change to the sepcification of the language,
but it will have no impact on existing programs. That makes it
a small change overall. The benefit comes from having language
constructs be well-defined, so that programs will not silently
change behavior when their environment changes. By the time
people are at the point where they are breaking up their code
to explicitly specify the order it's already too late. They are
most likely doing so because when they didn't do it their code
had mysterious failures that took them forever to track down.
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Tue, 2 Aug 2005 19:33:15 GMT Raw View
kanze@gabi-soft.fr wrote:
> IMHO, the whole argument is becoming ridiculous.
I agree with this. I have done some searching on Google and found the
thread below; Seems like a lot has already been said on this subject by
either side.
http://groups-beta.google.com/group/comp.std.c++/browse_frm/thread/69653e695e3b32b0
Anyway, I don't think that it's valid to say that Java "unquestionably"
does the right thing, considering the amount of disagreement.
C++ already allows vendors to enforce a stricter model than that
mandated by the standard - so the question is, are there any vendors
that implement the order Hyman Rosen proposes? If not, why? If there
are, then they can be studied (and used).
It's probably constructive to get implementations to support it before
arguing in favor of inclusion in a next standard.
~Marc.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 2 Aug 2005 19:52:26 GMT Raw View
Marc Schoolderman wrote:
> It's probably constructive to get implementations to support it before
> arguing in favor of inclusion in a next standard.
What for? We already know that compilers can sequence
things in the proper order, because they do it for
statements.
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Tue, 2 Aug 2005 21:25:06 GMT Raw View
Hyman Rosen wrote:
>> It's probably constructive to get implementations to support it before
>> arguing in favor of inclusion in a next standard.
> What for? We already know that compilers can sequence
> things in the proper order, because they do it for
> statements.
Politics. The C++ committee isn't writing a compiler for you, after all.
Furthermore, I doubt the committee is going to decree something that is
contrary to what a lot of current implementations do.
Better to take the bottom-up approach and "establish existing practice".
If there is an decent implementation that has your proposed properties,
that adds a significant amount of weight to your side.
I fail to see the objections someone can have to this.
~Marc.
---
[ 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: "Andrei Alexandrescu (See Website for Email)" <seewebsiteforemail@moderncppdesign.com>
Date: 3 Aug 2005 15:40:22 GMT Raw View
kanze@gabi-soft.fr wrote:
> IMHO, the whole argument is becoming ridiculous. On one hand,
> some people are claiming that there might be a machine somewhere
> where the freedom to reorder might make a difference, and far
> more unlikely, that this difference will be measurable in code
> where the compiler could not reorder simply under the as if
> rule. Claiming -- to date, no one has ever really shown a case
> where it's true.
What those people might not know is that modern compiler and processor
technology does enable reordering in a lot of the cases that matter.
The existing rule only allowed the compiler to not spend time on
proving that reordering is safe; that would have slowed compilation down.
In the case of function calls, the function call and execution
overhead would dwarf put the overhead (if any!) of putting things on
the stack in a different order. As Hyman has noted, "push" shouldn't
be thought of as faster just because it's a machine instruction. Int
the RISC core it's still the well-known sequence of operations
(decrement stack pointer register and store a register through it). It
could actually be argued that adjusting the stack pointer only once
and putting everything on the stack via indexed access is faster on
many machines. Of course, by today's rule implementations can use a
similar code generation strategy. What I'm saying is that "push"ing
isn't the fastest way out there.
In the case of expressions that could benefit from reordering, there's
good news, too - today's compilers routinely reorder code whenever
behavior is conserved, in order to reveal and exploit
instruction-level parallelism. Mostly cases that would be undefined by
today's rule - such as f(++i, ++i) - would be executed
"conservatively". In addition, some cases in which the compiler can't
prove lack of aliasing might generate more conservative code. I'd
think those cases are in minority, and that the performance loss in
those cases is also exceedingly small.
> On the other, you have people arguing for simple predictability,
> and meeting intuitive programmer expectations.
And it's about time to increase awareness about these issues.
So, James and I are pulling the same direction... now don't tell me
you gave up on SESE. :o)
Andrei
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Tue, 26 Jul 2005 01:52:37 GMT Raw View
Hyman Rosen wrote:
> Evaluation should proceed
> left-to-right. First the function name or expression itself is
> evaluated, then each parameter is initialized in turn from its
> argument expression, and that expression is fully evaluated with
> all side effects completed before evaluation of the next begins.
> If an exception is thrown during this process, then all already-
> initialized parameters are destructed. That is the only sane and
> sensible way to define the process.
Then, you'll still have problems in cases like these;
istream_iterator<int> w(cin);
if( *w++ < *w++ ) ...
One of the things I have come to appreciate about C(++) is that the
freedom of expressiviness comes with an equal responsibility not to cram
too much in one statement.
~Marc.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 26 Jul 2005 01:51:38 GMT Raw View
Marc Schoolderman wrote:
> If C++ mandated an evaluation order, this means inefficiency for
> calling conventions which don't match it, just so that 5 people will get
> their degenerate code to work.
No. First and foremost, it means that code will work
the same way on all platforms, instead of encountering
implementation dependencies that may change its behavior
when porting to a different platform/compiler/version.
Second, pushing an argument onto the call stack is no
more efficient than first allocating sufficient space
for all the arguments and then simply moving each
parameter into the appropriate slot.
Third, non-legacy architectures tend to pass their
parameters in registers rather than the stack.
Fourth, unless a particular function call actually
contains order dependencies, the compiler can do the
evaluations in any order anyway, under the as-if rule.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 26 Jul 2005 01:52:56 GMT Raw View
Marc Schoolderman wrote:
> Then, you'll still have problems in cases like these;
> istream_iterator<int> w(cin);
> if( *w++ < *w++ ) ...
No I won't. I advocate that C++ must have a fully specified
order of evaluation, including the completion of side-effects.
This order is essentially Java's - strictly left-to-right,
operands before operation. In the expression above, if w has
class type then the expression is
if (*w.operator++(1) < *w.operator++(1))
and it will be evaluated as-if the following:
auto r1 = w.operator++(1);
auto v1 = *r1;
auto r2 = w.operator++(1);
auto v2 = *r2;
if (v1 < v2) ...
If w has built-in type, then as-if the following:
auto r1 = w++;
auto v1 = *r1;
auto r2 = w++;
auto v2 = *r2;
if (v1 < v2) ...
I'm using the 'auto var' notation to mean temporary variables
of the appropriate result type of the operators.
Also, if any expression is an lvalue, its object identity is
captured when it is evaluated and remains fixed thereafter:
i = 0; a[i++] = ++i; // a[0] = 2;
---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: Tue, 26 Jul 2005 11:18:34 CST Raw View
Chris Jefferson wrote:
> I had a quick poke, and it looks to me like it is (slightly)
> more efficent to push the arguments onto the call stack
I really doubt that it makes much difference, if any.
For one thing, there's the cache - you're putting the
parameters into consecutive memory locations. Then
there's all the pre-fetching and speculative execution.
You can read <http://www.agner.org/assem/pentopt.pdf>
for a ton of detail.
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Tue, 26 Jul 2005 16:17:06 GMT Raw View
(I'll keep my fingers crossed and hope my newsreader will let this post
through just once, which is quite enough..:)
Hyman Rosen wrote:
> No. First and foremost, it means that code will work
> the same way on all platforms, instead of encountering
> implementation dependencies that may change its behavior
> when porting to a different platform/compiler/version.
I think this is negligible compared to other issues like a system
library causing subtleties, or code that relies on implementation
defined properties of integer types.
> Second, pushing an argument onto the call stack is no
> more efficient than first allocating sufficient space
> for all the arguments and then simply moving each
> parameter into the appropriate slot.
This isn't true on every architecture. Of course it's possible to
allocate a chunk of memory on the stack and assign to the available
memory slots. However, there is no free lunch;
"Replacing PUSH and POP instructions with MOV instructions can reduce
stack pointer dependencies and uses fewer execution resources. This
optimization is usually most effective in smaller routines. Excessive
use of this optimization can result in increased code size as MOV
instructions are considerably larger than PUSH and POP instructions."
(=A75.13 in http://www.amd.com/us-en/assets/content_type/
white_papers_and_tech_docs/25112.PDF.)
C++ should leave implementation decisions to the implementors.
> Third, non-legacy architectures tend to pass their
> parameters in registers rather than the stack.
You cannot afford to disregard register-deprived "legacy" architectures,
since one is in very wide use indeed(!), and likely to remain so for at
least another decade.
I also think a lot of embedded systems fall in this category.
> Fourth, unless a particular function call actually
> contains order dependencies, the compiler can do the
> evaluations in any order anyway, under the as-if rule.
This isn't good enough, since everything except basic operations on
built-in types can throw, strapping the compiler in a straight-jacket.
Regarding your other post - I am not convinced that giving obfuscated
statements like;
i =3D 0; a[i++] =3D ++i; // a[0] =3D 2;
well defined behaviour will have any practical benefit for anybody not
involved in the IOCCC. :)
~Marc.
---
[ 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: caj@cs.york.ac.uk (Chris Jefferson)
Date: Tue, 26 Jul 2005 18:33:34 GMT Raw View
Marc Schoolderman wrote:
> Steven T. Hatton wrote:
>
>> Do compilers really take advantage of this flexibility? How much does it
>> buy? Has the theoretical problem actually manifested itself in
>> production
>> code? Would specifying order on the evaluation of function arguments
>> impose great hardship on implementers? Would it adversely impact
>> execution
>> speed, compile time, or code size? How much?
>
>
> If C++ mandated an evaluation order, this means inefficiency for
> calling conventions which don't match it, just so that 5 people will get
> their degenerate code to work.
While I think I now agree the inefficency is too great, I do think
saying "5 people" and "degenerate code" is a little strong, espically as
more and more operators are overloaded in interesting ways. Do you consider:
cout << f() << f() << f() << std::endl
Degenerate code? and how often do you think that some people may have
written something like that, not realising the order of the executions
of f() is implementation-specific?
---
[ 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: caj@cs.york.ac.uk (Chris Jefferson)
Date: Tue, 26 Jul 2005 18:33:20 GMT Raw View
(Apologises that this message drifts slightly implementation-specific,
but it is I feel unavoidable considering the context).
Hyman Rosen wrote:
> Second, pushing an argument onto the call stack is no
> more efficient than first allocating sufficient space
> for all the arguments and then simply moving each
> parameter into the appropriate slot.
>
While I personally would prefer if the order of execution was indeed
fixed, are you sure of this assertion? I had a quick poke, and it looks
to me like it is (slightly) more efficent to push the arguments onto the
call stack
> Third, non-legacy architectures tend to pass their
> parameters in registers rather than the stack.
>
I believe that it is standard on x86 to pass quite a lot of things on
the stack rather than in registers, at least compared to ppc.
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Tue, 26 Jul 2005 19:20:43 GMT Raw View
Chris Jefferson wrote:
> While I think I now agree the inefficency is too great, I do think
> saying "5 people" and "degenerate code" is a little strong, espically
> as more and more operators are overloaded in interesting ways.
I stand corrected. The semantics of "cout <<" (especially the kind of
'serializing' work it does) does indeed strongly suggest an evaluation
order that the language doesn't provide.
I wrote that sentence in light of the GotW article. I do consider the
examples in that article 'degenerate', and think the author chose them
deliberately to demonstrate why to avoid such code.
> Do you consider: cout << f() << f() << f() << std::endl
> Degenerate code? and how often do you think that some people may have
> written something like that, not realising the order of the executions
> of f() is implementation-specific?
You're right, this might be more common, especially because C/C++
doesn't make a sharp distinction between 'procedures' and 'functions'
and you end up with a lot of routines which are a bit of both.
This causes problems unrelated to evaluation order as well:
cout << asctime(time1) << " to " << asctime(time2) << endl;
On the other hand, C++ does support making (and even enforcing) this
distinction in the form of inspector and modifier methods. If a class is
correctly written, inspector methods should be referentially
transparant, and the following;
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.
~Marc.
---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Sun, 24 Jul 2005 17:29:45 CST Raw View
Steven T. Hatton wrote:
> In clause 5.2.2/8 we read: "The order of evaluation of arguments is
> unspecified. All side effects of argument expression evaluations take
> effect before the function is entered. The order of evaluation of the
> postfix expression and the argument expression list is unspecified."
>
> Do compilers really take advantage of this flexibility? How much does it
> buy?
The unspecified order of execution doesn't change the fact that your
code is unsafe. Even if it was guaranteed that the first argument
always was fully evaluated, a sequence point occurs, and then the
second, if the second argument threw, the first would be lost.
---
[ 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: squell@alumina.nl (Marc Schoolderman)
Date: Mon, 25 Jul 2005 19:06:16 GMT Raw View
Steven T. Hatton wrote:
> Do compilers really take advantage of this flexibility? How much does it
> buy? Has the theoretical problem actually manifested itself in production
> code? Would specifying order on the evaluation of function arguments
> impose great hardship on implementers? Would it adversely impact execution
> speed, compile time, or code size? How much?
An equally important question is, "What would it gain?". This is not a
theoretical problem, it has a lot to do with calling conventions.
The basic model is that on a function call, a compiler pushes all its
arguments on a stack. Which means there are two main ways to do this,
left-to-right, or right-to-left.
This choice is not arbitrary. Most C/C++ implementations will probably
push right-to-left, so that the first argument will always be at a fixed
distance from the stack top.
However, other languages/systems will have different calling
conventions, and implementations usually offer special specifiers to
adjust to them (_pascal, _cdecl, _fastcall, _stdcall, etc.)
If C++ mandated an evaluation order, this means inefficiency for
calling conventions which don't match it, just so that 5 people will get
their degenerate code to work.
~Marc.
---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 25 Jul 2005 19:11:06 GMT Raw View
Ron Natalie wrote:
> The unspecified order of execution doesn't change the fact that your
> code is unsafe. Even if it was guaranteed that the first argument
> always was fully evaluated, a sequence point occurs, and then the
> second, if the second argument threw, the first would be lost.
But if the called function was written to take a pair of smart
pointers rather than plain pointers then things would be fine
(in a properly defined C++, that is). Evaluation should proceed
left-to-right. First the function name or expression itself is
evaluated, then each parameter is initialized in turn from its
argument expression, and that expression is fully evaluated with
all side effects completed before evaluation of the next begins.
If an exception is thrown during this process, then all already-
initialized parameters are destructed. That is the only sane and
sensible way to define the process.
---
[ 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: Marc Schoolderman <squell@tiscali.nl>
Date: Mon, 25 Jul 2005 16:06:25 CST Raw View
Hyman Rosen wrote:
> Evaluation should proceed
> left-to-right. First the function name or expression itself is
> evaluated, then each parameter is initialized in turn from its
> argument expression, and that expression is fully evaluated with
> all side effects completed before evaluation of the next begins.
> If an exception is thrown during this process, then all already-
> initialized parameters are destructed. That is the only sane and
> sensible way to define the process.
Then, you'll still have problems in cases like these;
istream_iterator<int> w(cin);
if( *w++ < *w++ ) ...
One of the things I have come to appreciate about C(++) is that the
freedom of expressiviness comes with an equal responsibility not to cram
too much in one statement.
~Marc.
---
[ 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 ]