[comp.lang.c] What does ANSI C say about short circuit evaluation?

gram@uctcs.uucp (Graham Wheeler) (05/22/91)

The following question has caused a bit of debate here in the last couple of
days. There are two parts:

i) Does ANSI C say that compilers can rearrange the order of expression 
	evaluation?

ii) Does it say that Boolean expressions must be evaluated with short-
	circuit evaluation?

We think the answers to both of these are yes, but we aren't sure. This
would mean that a statement like:

	if (ptr && ptr->next) ...

could potentially cause a segmentation violation on a system with meory
protection if the compiler was stupid enough to try to evaluate the second
(more complex) subexpression first - ie, one cannot rely on short-circuit
evaluation to prevent this from happening.

This doesn't bother me much as I tend to write such pointer expressions as

	if (ptr) if (ptr->next) ...

for safety, but it may cause some elusive buggy behaviour.

Preferably e-mail your responses, thanks.

Graham Wheeler <gram@cs.uct.ac.za> | "That which is weak conquers the strong,
Data Network Architectures Lab     | that which is soft conquers the hard.
Dept. of Computer Science          | All men know this; none practise it"
University of Cape Town            |		Lao Tzu - Tao Te Ching Ch.78

rearl@watnxt3.ucr.edu (Robert Earl) (05/23/91)

In article <1991May22.092404.25297@ucthpx.uct.ac.za> gram@uctcs.uucp (Graham Wheeler) writes:
 
|   The following question has caused a bit of debate here in the last couple of
|   days. There are two parts:
|
|   i) Does ANSI C say that compilers can rearrange the order of expression 
|	   evaluation?

For the most part, yes.  K&R II, section 2.12, says "C does not
specify the order in which the operands of an operator are evaluated.
(The exceptions are &&, || ?:, and ','.)"

|   ii) Does it say that Boolean expressions must be evaluated with short-
|	   circuit evaluation?

Yes.  Way back in section 1.5.4, it states: "Expressions connected by
&& or || are evaluated left to right, and it it guaranteed that
evaluation will stop as soon as the truth or falsehood is known."

|   We think the answers to both of these are yes, but we aren't sure. This
|   would mean that a statement like:
|
|	   if (ptr && ptr->next) ...
|
|   could potentially cause a segmentation violation on a system with meory
|   protection if the compiler was stupid enough to try to evaluate the second
|   (more complex) subexpression first - ie, one cannot rely on short-circuit
|   evaluation to prevent this from happening.

Will never happen (with a conforming compiler-- and likely with any
popular old compiler).  Isn't that good news?

I'm sure someone will gladly post an example or two of compilers that
didn't follow this, and caused some fun bugs.  :-)


--
______________________________________________________________________
			\					
 robert earl		/	"Love is a many splintered thing"
 rearl@watnxt3.ucr.edu	\		--Sisters of Mercy
 rearl@gnu.ai.mit.edu	/

henry@zoo.toronto.edu (Henry Spencer) (05/24/91)

In article <1991May22.092404.25297@ucthpx.uct.ac.za> gram@uctcs.uucp (Graham Wheeler) writes:
>i) Does ANSI C say that compilers can rearrange the order of expression 
>	evaluation?

Not unless it can guarantee that the results (including things like
overflow exceptions, if any) are the same.  This is a tightening-up
of the specs relative to old C.

>ii) Does it say that Boolean expressions must be evaluated with short-
>	circuit evaluation?

If you're referring to the && and || operators, C has *always* required 
short-circuit evaluation of these, and ANSI C confirms this.  If you're
referring to the & and | operators, short-circuit evaluation is forbidden
unless the results (including side effects) are exactly the same.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (05/25/91)

In article <1991May22.092404.25297@ucthpx.uct.ac.za>, gram@uctcs.uucp (Graham Wheeler) writes:

> i) Does ANSI C say that compilers can rearrange the order of
>    expression evaluation?

In general, yes.  There are a few exceptions; notably, the &&, ||, ?:,
and , operators promise some things about the order in which their
operands are evaluated (and in some cases, about whether certain
operands are evaluated at all).

> ii) Does it say that Boolean expressions must be evaluated with
>     short-circuit evaluation?

When using the short-circuit operators && and ||, yes.

> We think the answers to both of these are yes, but we aren't sure.

Mostly.  The second one is yes; the first one is a qualified yes.

> This would mean that a statement like:

>       if (ptr && ptr->next) ...

> could potentially cause a segmentation violation on a system with
> meory protection if the compiler was stupid enough to try to evaluate
> the second (more complex) subexpression first - ie, one cannot rely
> on short-circuit evaluation to prevent this from happening.

No, this is not a danger.  A compiler producing code for that example
that evaluates ptr->next when ptr == 0 (ie, when ptr is a null pointer
of its type) is simply broken.

                                        der Mouse

                        old: mcgill-vision!mouse
                        new: mouse@larry.mcrcim.mcgill.edu

xc215119@seas.gwu.edu (David E. O'Brien) (05/26/91)

In article <1991May22.092404.25297@ucthpx.uct.ac.za> gram@uctcs.uucp (Graham Wheeler) writes:
>The following question has caused a bit of debate here in the last couple of
>days. There are two parts:
>
>i) Does ANSI C say that compilers can rearrange the order of expression 
>	evaluation?
>
>ii) Does it say that Boolean expressions must be evaluated with short-
>	circuit evaluation?
>

Yes, ANSI C requires boolean short circuiting and that the C compiler must
process if(...) in the order from left to right.  In fact you can read this
from K & R 2nd ed.  They even say that many, many C programmers DEPEND on
this fact and in your life as a programmer you are probably going to come
upon some code that depends on this, so get used to it.

-- David O'Brien