T
TB
This is a repost of something I had posted four months ago with no
response, I'm hoping to get some feedback...
From the Microsoft .net Core Reference (pg. 104)
C# shares the AND (short-circuit) operator (&&) with C and C++.
This operator works with two operands, evaluating as 'true' if
both operands are true.
But later (pg. 124)
Behind the scenes, the compiler combines the 'true', 'false',
and '&' operators in the following way to evaluate the &&
operator:
if (Foo.false(a) != true)
return Foo.true(Foo.operator & (a, b));
else
return Foo.true(a);
I have verified this by overriding the 'true', 'false', and '&'
operators
to display tracing information.
Now this raises a couple of issues in my mind...
1) This seems horribly inefficient. For example, if 'a', the left
hand
object, evaluates to false we end up determining it's boolean value
twice in
order to get our return value. The same is true of operator ||.
Wouldn't a much simpler, cleaner, and *more correct* way to do this
be:
&& ||
----------------- -----------------
if (Foo.false(a)) if (Foo.true(a))
return false; return true;
else else
return Foo.true(b); return Foo.true(b);
2) The short-circuit operator is *not* just a simple boolean operation
since it relies on the implementation of operator& (which returns a
new
object). It is possible for both 'a' and 'b' to separately evaluate
as
true but for 'a & b' to evaluate as false. Yes, yes, I know... this
is
probably a sign of a design mistake, but consider the following
example...
struct MyInt
{
private int _val;
public MyInt(int v) { _val = v; }
public Value
{
get { return _val; }
set { _val = value; }
}
static public bool operator true(MyInt a)
{
return a.Value != 0;
}
static public bool operator false(MyInt a)
{
return a.Value == 0;
}
static public MyInt operator &(MyInt a, MyInt b)
{
return new MyInt(a.Value & b.Value);
}
}
i.e. a pretty simple class that basically just encapsulates a single
int.
Now consider this...
MyInt a(7);
MyInt b(32);
if (a)
Console.WriteLine("a is true!"); // <== non-zero is true
else
Console.WriteLine("a is false!");
if (b)
Console.WriteLine("b is true!"); // <== non-zero is true
else
Console.WriteLine("b is false!");
if (a && b)
Console.WriteLine("a && b is true!");
else
Console.WriteLine("a && b is false!"); // (7 & 32) == 0
The C# method of using the bitwise-AND to implement the logical-AND
(short circuiting) leads to this confusing result.
Comments??
-- TB
response, I'm hoping to get some feedback...
From the Microsoft .net Core Reference (pg. 104)
C# shares the AND (short-circuit) operator (&&) with C and C++.
This operator works with two operands, evaluating as 'true' if
both operands are true.
But later (pg. 124)
Behind the scenes, the compiler combines the 'true', 'false',
and '&' operators in the following way to evaluate the &&
operator:
if (Foo.false(a) != true)
return Foo.true(Foo.operator & (a, b));
else
return Foo.true(a);
I have verified this by overriding the 'true', 'false', and '&'
operators
to display tracing information.
Now this raises a couple of issues in my mind...
1) This seems horribly inefficient. For example, if 'a', the left
hand
object, evaluates to false we end up determining it's boolean value
twice in
order to get our return value. The same is true of operator ||.
Wouldn't a much simpler, cleaner, and *more correct* way to do this
be:
&& ||
----------------- -----------------
if (Foo.false(a)) if (Foo.true(a))
return false; return true;
else else
return Foo.true(b); return Foo.true(b);
2) The short-circuit operator is *not* just a simple boolean operation
since it relies on the implementation of operator& (which returns a
new
object). It is possible for both 'a' and 'b' to separately evaluate
as
true but for 'a & b' to evaluate as false. Yes, yes, I know... this
is
probably a sign of a design mistake, but consider the following
example...
struct MyInt
{
private int _val;
public MyInt(int v) { _val = v; }
public Value
{
get { return _val; }
set { _val = value; }
}
static public bool operator true(MyInt a)
{
return a.Value != 0;
}
static public bool operator false(MyInt a)
{
return a.Value == 0;
}
static public MyInt operator &(MyInt a, MyInt b)
{
return new MyInt(a.Value & b.Value);
}
}
i.e. a pretty simple class that basically just encapsulates a single
int.
Now consider this...
MyInt a(7);
MyInt b(32);
if (a)
Console.WriteLine("a is true!"); // <== non-zero is true
else
Console.WriteLine("a is false!");
if (b)
Console.WriteLine("b is true!"); // <== non-zero is true
else
Console.WriteLine("b is false!");
if (a && b)
Console.WriteLine("a && b is true!");
else
Console.WriteLine("a && b is false!"); // (7 & 32) == 0
The C# method of using the bitwise-AND to implement the logical-AND
(short circuiting) leads to this confusing result.
Comments??
-- TB