I'm learning C# and have been messing about on the Pex for fun site. The site challenges you to re-implement a secret algorithm, by typing code into the site and examining how the inputs and outputs differ between your implementation and the secret implementation.
Anyway, I got stuck on a basic code duel called XAndY.
From the name it seemed obvious that the answer was just:
public static bool Puzzle(bool x, bool y)
{
return x && y;
}
However, this was incorrect and Pex informed me that the following inputs produced a different result than the secret implementation:
Input:
x:true y:true (0x02)
Output:
my implementation: true (0x02)
secret implementation: false
Mismatch Your puzzle method produced the wrong result.
Code: Puzzle(true, PexSafeHelpers.ByteToBoolean((byte)2));
After a lot of confusion trying to compare different types of true, I realised that the implementation that Pex was looking for was actually just using a bitwise AND:
return x & y;
I thought that for both semantic and short-circuiting reasons you should use logical &&
for comparing boolean values, but regardless:
x & y
and x && y
definitively do not have the same outputs for all possible bool arguments? (or could it be something buggy in Pex?)true
in C#? If so, how?X-rays are commonly produced in X-ray tubes by accelerating electrons through a potential difference (a voltage drop) and directing them onto a target material (i.e. tungsten). The incoming electrons release X-rays as they slowdown in the target (braking radiation or bremsstrahlung).
When X-ray radiation is absorbed within our bodies, it can damage molecular structures and potentially cause harm. Very high doses of radiation cause damage to human cells, as evidenced by skin burns, loss of hair, and increased incidence of cancer.
Now we come to the most important question, How much of Xray is safe for a person in his lifetime? Xray is generally measured or compared with normal environment radiation. The American College of Radiology recommends 100mSv in a lifetime which is equal to 10000 chest Xrays or 25ct chest scans.
The puzzle is exploiting what, in my opinion, is a bug in the C# compiler. (The bug affects VB.NET as well.)
In the C# 5.0 specification, §4.1.8 says that "The possible values of type bool
are true
and false
", and §7.11.3 says that operator &(bool x, bool y)
is a logical operator:
The result of
x & y
istrue
if bothx
andy
aretrue
. Otherwise, the result isfalse
.
It's obviously a violation of the specification for true & true
to yield false
. What's going on?
At run time, a bool
is represented by a 1-byte integer. The C# compiler uses 0 to represent false
and 1 to represent true
. To implement the &
operator, the C# compiler emits a bitwise AND
instruction in the generated IL. At first glance, this seems to be okay: bitwise AND
operations involving 0 and 1 correspond exactly with logical AND
operations involving false
and true
.
However, §III.1.1.2 of the CLI specification explicitly allows a bool
to be represented by an integer other than 0 or 1:
A CLI Boolean type occupies 1 byte in memory. A bit pattern of all zeroes denotes a value of false. A bit pattern with any one or more bits set (analogous to a non-zero integer) denotes a value of true.
By going beyond the scope of C#, it is indeed possible—and perfectly legal—to create a bool
whose value is, say, 2, thus causing &
to behave unexpectedly. This is what the Pex site is doing.
Here's a demonstration:
using System;
using System.Reflection.Emit;
class Program
{
static void Main()
{
DynamicMethod method =
new DynamicMethod("ByteToBoolean", typeof(bool), new[] { typeof(byte) });
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Load the byte argument...
il.Emit(OpCodes.Ret); // and "cast" it directly to bool.
var byteToBoolean =
(Func<byte, bool>)method.CreateDelegate(typeof(Func<byte, bool>));
bool x = true;
bool y = byteToBoolean(2);
Console.WriteLine(x); // True
Console.WriteLine(y); // True
Console.WriteLine(x && y); // True
Console.WriteLine(x & y); // False (!) because 1 & 2 == 0
Console.WriteLine(y.Equals(false)); // False
Console.WriteLine(y.Equals(true)); // False (!) because 2 != 1
}
}
So the answers to your questions are:
x & y
and x && y
to have different values. However, this behavior violates the C# specification.Boolean.Equals
(as shown above) to differentiate between true
values. However, this behavior violates the CLI specification of Boolean.Equals
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With