как это может случиться? - PullRequest
       5

как это может случиться?

1 голос
/ 26 декабря 2009
struct a { public int x; }
struct c { public byte x; }
unsafe class Program
{
    static void Main(string[] args)
    {
        a V = new a();
        V.x = 1;
        c* b = (c*)(void*)&V;
        for(int n = 0;n != 300;n++) b->x++;
        Console.WriteLine(V.x);
        Console.ReadKey(true);
    }
}

45

это действительно возвращает 45.
почему не выдает никаких исключений?

1 Ответ

6 голосов
/ 26 декабря 2009

Почему вы ожидаете, что оно выдаст исключение?

По умолчанию код C # не проверен , что означает, что переполнения и тому подобное просто игнорируются. Вы можете найти текущие настройки проекта для этого параметра, перейдя в свойства проекта, вкладка «Сборка» и нажав кнопку «Дополнительно» на вкладке «Содержание». В появившемся диалоговом окне у вас должна быть «Проверка арифметического переполнения / недополнения». Этот параметр по умолчанию снят.

В этом случае вы увеличиваете первый байт 32-битного (4-байтового) int-значения x, проходя через указатель, приведенный к c, и увеличиваете его в 300 раз.

Это увеличивает его 256 раз, что приводит к тому, что оно возвращается к 0, а затем еще к 44 разам. Так как это началось в 1, это теперь 45.

Вы можете легко проверить это, выполнив следующий код:

Byte b = 255;
b++;
Console.Out.WriteLine("b=" + b);

Вы получите:

Ь = 0

не исключение переполнения.

Сказав все это, вы, вероятно, не должны использовать указатели и небезопасный код, пока он вам действительно не понадобится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...