Re: Order of argument evaluation in C++, etc.

chase@centerline.com (David Chase)
Mon, 28 Aug 1995 16:57:38 GMT

          From comp.compilers

Related articles
[41 earlier articles]
Re: Order of argument evaluation in C++, etc. jmccarty@spdmail.spd.dsccc.com (1995-08-24)
Re: Order of argument evaluation in C++, etc. daniels@cse.ogi.edu (1995-08-24)
Re: Order of argument evaluation in C++, etc. pardo@cs.washington.edu (1995-08-25)
Re: Order of argument evaluation in C++, etc. hbaker@netcom.com (1995-08-25)
Re: Order of argument evaluation in C++, etc. jan@neuroinformatik.ruhr-uni-bochum.de (1995-08-25)
Re: Order of argument evaluation in C++, etc. stefan.monnier@epfl.ch (Stefan Monnier) (1995-08-28)
Re: Order of argument evaluation in C++, etc. chase@centerline.com (1995-08-28)
Re: Order of argument evaluation in C++, etc. hbaker@netcom.com (1995-08-30)
| List of all articles for this month |
Newsgroups: comp.compilers
From: chase@centerline.com (David Chase)
Keywords: optimize, C
Organization: CenterLine Software
References: 95-08-067 95-08-177
Date: Mon, 28 Aug 1995 16:57:38 GMT

Thomas Way <way@cis.udel.edu> writes:
> At the risk of sounding a bit naive in this whole debate
> over order of evaluation


Naive, but indeed only a bit. My focus on this may be a weird
combination of knowing too many people who've worked in
safety-critical industries (aerospace, medical, chemical plant
operation and design), and working (in a former job) with an
exceptionally conscientious and paranoid bunch to build an
optimizing back-end.


Basically, bugs are bad, and humans are unreliable.
Code must be tested, and any changed code must be tested. Bugs
detected must then be traced back to their root causes, which
must then be corrected, and retested. Productivity is more or
less determined by how quickly you can discover, fix, and
retest a program. In particular, this is most significant in
the months leading up to product release, when slips are worst.
Humans are not guaranteed to fix only the offending bug, or to
apply the fix correctly, or to type correctly, or to adhere to
a particular set of style guidelines, or to not *change* the
style guidelines mid-project. Sometimes, they use their tools
incorrectly (configuration management software can do both
wonderful and terrible things). Sometimes, they "know" that
some particular step (e.g., a rebuild with "make") is
unnecessary, and skip it.


And, in this messy effort, minimizing gratuitous changes to the
code and its behavior is a good thing. You want compiled code
and debuggable code to have the same behavior, because
otherwise you'll end up debugging optimized code at the
assembly language level (usually). You very much want
repeatable bugs, that survive small perturbations to the
software, so that they don't accidentally disappear, only to
reappear months later (you may also choose to intentionally
tweak the system in an effort to smoke out latent bugs, but
once those bugs are found, you want to be able to reproduce
them).


> 1) Perhaps if the order of evaluation of expressions whose
> results are passed as arguments is so important, these
> expressions should be evaluated prior to the actual
> fuction call. ...


Entirely true, and I can well imagine a coding style that
would enforce this. The difficulty is, this is cumbersome,
contrary to typical C coding style, and a pain to check.
What's this programming language for, after all?


> 2) In my opinion, it makes code difficult to read and support
> when function calls contain all sorts of expressions that
> are evaluated. Single statements tend to span lines more
> than necessary, and this alone slows down the task of
> digging through a year or two later to improve or otherwise
> rework pre-existing code... Particularly if it is not your
> own handiwork.


Generally, I agree with this, but in practice these things
happen, despite the best of stylistic intentions. When they
do happen, I prefer that the program still behave predictably.


There may be additional complications with C++. I'm not
entirely clear on this, and it seemingly varies from compiler
to compiler and from draft standard to draft standard, but
writing


    F(G(),H());


may not be the same as


    Gtype g = G();
    Htype h = H();
    F(g,h);


Or, perhaps I wrote it wrong -- maybe I was supposed to use
references. (Who can tell?) Throw in a few macros, and some
template instantiations with some overloaded operators (what, you
thought that "a + b + c" had no side-effects?) and I feel no shame at
all in saying that I am hopelessly confused, and more than a little
worried about exactly what's going on.


So, when I look at this potential mess, I ask myself: "What is the
least-perturbation change the The Language (not its compilers, though
minimizing that doesn't hurt, either) that will increase
reliability?" I cannot ban templates, or copy constructors, or
overloaded assignment -- all those things would break programs. I
CAN define an order of evaluation (and, in the compilers with which I
have worked, this is not a big deal, either).


I hope this explains my motivation somewhat. If you want a
generalized introduction to this sort of paranoia, go read _Normal
Accidents_ by Charles Perrow (Basic Books, a division of
HarperCollins, 1984).


speaking for myself,


David Chase
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.