Topic: SHORT-CIRCUIT EXPRESSION


Author: sunil.puri@toronto.can.ipguild.org
Date: Mon, 26 Dec 94 00:25:28
Raw View
I have been studying compiler theory and would like to know how a C++ compiler
(or a C compiler for this matter) would evaluate an expression of the form
(E1 || E2 && E3) since it (C/C++) employs the use of short-circuit expressions.
Since the above expression also reads (E3 && (E1 || E2)), then would a C/C++
compiler evaluate it that way so has to avoid evaluating
(E1 || E2) unneccessarily?



Sunil Puri

sunil.puri@toronto.can.ipguild.org




Author: stidev@gate.net (Solution Technology)
Date: 27 Dec 1994 01:28:11 GMT
Raw View
sunil.puri@toronto.can.ipguild.org wrote:

: I have been studying compiler theory and would like to know how a C++ compiler
: (or a C compiler for this matter) would evaluate an expression of the form
: (E1 || E2 && E3) since it (C/C++) employs the use of short-circuit expressions.

: Since the above expression also reads (E3 && (E1 || E2)), then would a C/C++
????????????????????????????????????????????????
: compiler evaluate it that way so has to avoid evaluating
: (E1 || E2) unneccessarily?

( E1 || E2 && E3 ) gets you  ( E1 orif ( E2 andif E3 ))

and a compiler could choose to evaluate the expression literally without
any optimizations.  The degree of optimization is determined by the
implementors and are frequently over(improperly) optimized by those
novices in the field of optimization.  The most difficult part of
optimization is to determine when it is unsafe to perform an optimization
because of effects on other parts of a program.

Ken Walter





Author: mat@mole-end.matawan.nj.us
Date: Tue, 27 Dec 1994 06:45:57 GMT
Raw View
In article <9412260025.A1903wk@toronto.can.ipguild.org>, sunil.puri@toronto.can.ipguild.org writes:
>
> I have been studying compiler theory and would like to know how a C++ compiler
> (or a C compiler for this matter) would evaluate an expression of the form
> (E1 || E2 && E3) since it (C/C++) employs the use of short-circuit expressions.
> Since the above expression also reads (E3 && (E1 || E2)), then would a C/C++
> compiler evaluate it that way so has to avoid evaluating
> (E1 || E2) unneccessarily?

`Short-circuit evaluation' is NOT commutative.

What you suggest, compiler reordering of tests for optimization, is
exactly what _cannot_ safely be done.

Short-circuit evaluation, as performed by C/++, means that the _RHS_ of
an && or || won't be evaluated unless it must be.  This means that it
is possible to write expressions that would be undefined if they were
not `guarded' by the LHS expression:

 const char* s = .. .. ..
  :
  :
  :
 if( s
  && strcmp( s, "abcd" ) )
 {
  .. .. ..


 enum { NO_VAL = -1, INVAL = -2 };
  :
  :
  :

 if( i < 0
  || a[ i ] < 0
  || xck[ a[ i ] ] < 0
  || gv[ a[ i ] ] == N_VAL )
 {
  :
  :
  :


As to how it is actually done, let's take the example of

 if( i < 0
  || a[ i ] < 0 )
 {
  .. .. .. stuff .. .. ..
 }
 else
 {
  .. .. .. other stuff .. .. ..
 }

This is done internally by converting the code into something like this:

 if( i >= 0 ) goto take_else;
 if( a[ i ] >= 0 ) goto take_else;

 take_if:
  .. .. .. stuff .. .. ..
  goto done;
 take_else:
  .. .. .. other stuff .. .. ..
 done:

It is exactly the ability to write tests whose validity depends upon the
tests before that makes short-circuit evaluation more expressive and more
useful than non-short-circuit evaluation.
--
 (This man's opinions are his own.)
 From mole-end    Mark Terribile
 mat@mole-end.matawan.nj.us, Somewhere in Matawan, NJ
 (Training and consulting in C, C++, UNIX, etc.)