Я недавно читал this article от Dave Detlefs, в котором он представляет несколько случаев, когда CLR выполняет проверку границ массива. Я решил проверить это сам, так что я сделал следующее:Проверка границ массива Исправление в CLR?
- Открытый Visual Studio 2010 Ultimate SP1
- Создано новый C# проект типа Console Application (таргетинг .NET 4 Client Profile по умолчанию)
Добавлен следующий код (все суб-методы взяты непосредственно из статьи):
class Program { static void Main(string[] args) { int[] array = new int[30]; Test_SimpleAscend(array); Test_SimpleRedundant(array, 3); foreach (int i in array) { Console.WriteLine(i); } } static void Test_SimpleAscend(int[] a) { for (int i = 0; i < a.Length; i++) a[i] = i; } static void Test_SimpleRedundant(int[] a, int i) { int k = a[i]; k = k + a[i]; } }
Переключение в режим Release; проверить, что «Оптимизировать код» проверяется в настройках Строительства
- Добавлена контрольная точка для каждого доступа к массиву, начавших отладки (F5) и открыл окно Dissassembly
Так вот dissassembly для [я] = я; в Test_SimpleAscend:
a[i] = i;
00000024 mov eax,dword ptr [ebp-4]
00000027 mov edx,dword ptr [ebp-8]
0000002a cmp eax,dword ptr [edx+4]
0000002d jb 00000034
0000002f call 64FD6E08
00000034 mov ecx,dword ptr [ebp-4]
00000037 mov dword ptr [edx+eax*4+8],ecx
КСС/Jb/вызова проверки границ, фактически заставляя вызов выполняться бросает IndexOutOfRangeException.
То же самое для всех доступов к массиву, включая избыточный доступ в Test_SimpleRedundant. Так что с моей методологией тестирования что-то не так, или CLR на самом деле не устраняет проверку границ? Надеюсь, я ошибаюсь, и если так, я хотел бы знать, как я могу действительно получить проверку границ массива.
Когда вы говорите «начатая отладка», я предполагаю, что вы запустили приложение * с прикрепленным отладчиком * из среды Visual Studio. В этом случае вам нужно убедиться, что компиляция JIT включена, потому что она не по умолчанию. Компилятор JIT - это тот, который выполняет эту оптимизацию, а не компилятор C#. –
Что вы ожидаете, если проверка границ отключена? Обычно это функция, которую люди ожидают иметь при использовании управляемого языка, такого как C#. –
Самый простой способ обеспечить оптимизацию на самом деле позволяет запустить приложение без отладки, а затем подключить к нему отладчик. – svick