Семантика полей 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 где необходимо.

Лучше всего избегать такого рода кода, ИМО. Вам это действительно нужно, или вам просто любопытно?

Другие вопросы по тегам