Семантика полей bool в явных типах макетов (ECMA-334)
Я пытаюсь найти, где в ECMA-334 (спецификация языка C#) определено следующее поведение. Исходная программа выглядит следующим образом.
static void Main(string[] args)
{
TestStruct a = new TestStruct();
a.byteValue = 1;
TestStruct b = new TestStruct();
b.byteValue = 2;
Console.WriteLine(string.Format("Result of {0}=={1} is {2}.",
a.boolValue, b.boolValue, a.boolValue == b.boolValue));
Console.WriteLine(string.Format("Result of {0}!={1} is {2}.",
a.boolValue, b.boolValue, a.boolValue != b.boolValue));
Console.WriteLine(string.Format("Result of {0}^{1} is {2}.",
a.boolValue, b.boolValue, a.boolValue ^ b.boolValue));
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
struct TestStruct
{
[FieldOffset(0)]
public bool boolValue;
[FieldOffset(0)]
public byte byteValue;
}
Результат исполнения следующий.
Result of True==True is False.
Result of True!=True is True.
Result of True^True is True.
Это нарушает оба раздела §14.9.4 и §14.10.3, поэтому я предполагаю, что в другом месте указано исключение, которое охватывает эти случаи. Обратите внимание, что это не влияет на код с использованием операций AND, OR, NAND или NOR, но может влиять на код с использованием операций XOR и / или логических двухусловных операций.
1 ответ
Я сомневаюсь, что это указано на всех. К тому времени, когда вы явно изложите свои структуры, вы, скорее всего, начнете действовать в зависимости от архитектуры и реализации.
Я сильно подозреваю, что поведение, которое вы видите, можно объяснить, представив, что все bool
Операции эффективно преобразуются в целочисленные операции, а затем (при необходимости) конвертируют результат, проверяя, является ли он ненулевым. Обычно это нормально, пока все bool
значения используют одно и то же значение в памяти (1 или 0), но в вашем случае вы даете ему неожиданное значение (2). Так что хотя a.boolValue
а также b.boolValue
оба правда, a.boolValue ^ b.boolValue
имеет эффект XORing двух задействованных байтов, давая 3, который все еще преобразуется в true
где необходимо.
Лучше всего избегать такого рода кода, ИМО. Вам это действительно нужно, или вам просто любопытно?