I'm having an argument with a co-worker about the difference between
the & and && operators when applied to boolean operands in C#. His
point of view is that the expression (false & expr2) might be optimised
at JIT-time and the second expression will not be evaluated. In my
opinion this would break the contract of the C# language if the JIT
compiler were to remove the call to expr2 entirely. I'm not saying that
it's good programming practice to depend on the side effects of expr2's
evaluation, all I'm saying is that it just feels _right_ to know that
both sides of the logical expression were evaluated.
I'd really appreciate any input from some of the CLR gurus out there.
Is there a difference between these operators in IL? Might a JIT
compiler conceivably shortcut the evaluation? Any other things I
missed?
Thanks,
Jono
if (str != null && str.Length != 0) ...
This is safe, as the second operand is not evaluated it the reference is
null. If both operands were evaluated, the second would throw an
NullReferenceException if the reference was null.
When using the & operator, both operands are always evaluated.
Both sides are evaluated with &. As you say, only evaluating one side
would be breaking the language spec. (If the JIT notices that it's
completely without side-effects, it could do some optimisation - but
you'd have to look at the generated code to know for sure.)
With &&, it's guaranteed that the RHS won't be evaluated if the LHS is
false.
This (and its equivalent for "or") allows for things like:
if (x==null || x.Length==0)
to be safe.
--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
false && expr2 is guaranteed never to evaluate expr2, just as
true || expr2 is guaranteed never to evaluate expr2.
whereas
false & expr2 is guaranteed to always evaluate expr2, just as
true | expr2 is guaranteed always to evaluate expr2.
The && and || operators are referred to as using McCarthy evaluation
(for us old-timers) or more recently "short-circuit" evaluation. In
general the && and || forms are preferred, and it is common C, C++, and
C# idiom to say things like:
if (myObject != null && myObject.BoolProperty)
{
... do something ...
}
void Test(bool b)
{
if (false & b)
{
Console.WriteLine("foo");
}
else
{
Console.WriteLine("boo");
}
}
gets compiled by csc into the following IL:
.method private hidebysig instance void Doo(bool b) cil managed
{
.maxstack 8
L_0000: ldstr "boo"
L_0005: call void [mscorlib]System.Console::WriteLine(string)
L_000a: ret
}
"Jonathan" <jono...@gmail.com> wrote in message
news:1146855848.3...@u72g2000cwu.googlegroups.com...
Well empirically && short circuits and & doesn;t (just tested it in VS2005).
If it makes the call in one situation it would be madness to sometimes not
make the call in others due to JIT optimization. The behavior of the code
would be non-deterministic depending on the mood of the JIT.
Regards
Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk
I would understand if the OP meant something different from what he had
written (e.g. "is expr2 evaluated if I type if (expr1 & expr2), if expr1
gets evaluated to false?"), but it was obvious to me that he asked about
evaluating & operator application to known "false" value and expression.
"Göran Andersson" <gu...@guffa.com> wrote in message
news:eHZKZqHc...@TK2MSFTNGP05.phx.gbl...
If you want to ensure expr2 is called then you should explicitly call it
before the if statement
bool expr2Result = expr2;
if (false && expr2Result)......
I think that is much more clear than
if (false & expr2)
especially as someone may come along at a later date and change it to &&
because they think they are "optimising" the code!
Pete
No it does not. The following code:
class Start
{
private static bool SideEffectMethod()
{
Console.WriteLine("Hello from SideEffectMethod");
return true;
}
[STAThread]
static void Main(string[] args)
{
if (false & SideEffectMethod())
{
Console.WriteLine("Hi here.");
}
}
}
Produces the output, "Hello from SideEffectMethod", which it would not
if the expression were optimized by the compiler.
Changing the & to a && results in no output.
I reckon that expr2 WILL possibly be optimised-away so long as the
JITter can tell that expr2 has no side effects.
--
Lucian