views:

788

answers:

9

In C# is it guaranteed that expressions are evaluated left to right?

For example:

myClass = GetClass();  
if (myClass == null || myClass.Property > 0)  
    continue;

Are there any languages that do not comply?

A: 

The evaluation order depends on the operator, in this case the boolean or (||) is defined to be what is commonly called short-circuiting, to make constructs like this work.

unwind
+9  A: 

You actually refer to a language feature called "short-circuiting logical expressions":

What this means is this: When the outcome of a logical expression cannot change anymore, e.g. when it is clear that the expression will evaluate to "true" or "false" no matter what, remaining parts of the expression will not be evaluated.

For example, C#, Java or JavaScript do that, and you can rely on it in those languages (to answer your question).

In your case, if MyClass is not null:

  • MyClass == null evaluates to false
  • since it is an "or" expression, the second part still can change the result, so it is evaluated
  • myClass.Property > 0 determines the end result

if MyClass is null:

  • MyClass == null evaluates to true
  • since it is an "or" expression, it does not matter what follows
  • no more evaluation is done, the end result is true

There are languages that do not short-circuit logical expressions. Classical VB is an example, here "myClass.Property > 0" would be evaluated and produce an error if MyClass was null (called "Nothing" in VB).

Tomalak
+5  A: 

Short-circuiting is described in section 7.11 of the C# 3.0 spec:

The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.

So yes, you're fine.

As for other languages - I never like to speak for all languages. In VB.NET, you can use OrElse and AndAlso which are short-circuited, but plain Or and And aren't.

Jon Skeet
+2  A: 

But be careful:

if you have something like

sprintf(buf, "%s %s", func1(&var), func2(&var));

with sideeffects on var, it is not defined (in C, i am not sure if the evaluation order is defined in other languages), in which order func1() and func2() are executed (it depends, in what order (left or right) the arguments are put on the stack and evaluated from there.

Peter Miehle
In C# the precise order is defined.
Martijn
A: 

I'm not sure, are you really interested in order or in short-circuit evaluation?

I'm not 100% sure, but as far as I know the order of evaluation will always be the same in C# (and I assume most if not all of .net languages). Short-circuit evaluation works as explained in the previous answers.

However, in C# you can choose not to short circuit using simple operators (& instead of &&). Normally you want to short-circuit, but it may be a case in which you want to execute all the evaluations.

Rafa G. Argente
A: 

The and/or operators in languages like Ada, Visual Basic, and Pascal do not short-circuit. They do provide extra operators to allow that functionality, such as "and then" and "or else" in Ada.

Firas Assaad
A: 

Python has short-circuit or and and operators.

S.Lott
A: 

In Java and Haskell && and || short-circuit as well.

Interesting aside: in Haskell this comes naturally with the language (you can define your own operators that do this), while in Java and C# it is specific for those two operators.

Martijn
A: 

Actually short-circuiting is part, but you also need to know whether the language guarantees left-to-right evaluation of those. For instance C (ANSI, ISO, C99) do NOT guarantee left-to-right evaluation. In the sample code it would be possible to check the value of Property before checking for NULL or do both simultaneously... most compilers don't, but there's nothing preventing it from doing that and being fully compliant with the spec. It even tells you NOT to write such code because of this.

Joe Tennies