Я недавно читал эту статью Дэйва Детлефса, в которой он представляет несколько случаев, когда CLR выполняет исключение проверки границ массива. Я решил проверить это сам, поэтому сделал следующее:
- Открыт Visual Studio 2010 Ultimate SP1
- Создан новый проект C # типа Консольное приложение (по умолчанию предназначен для .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];
}
}
Переключен в режим разблокировки; проверил, что "Оптимизировать код" отмечен в опциях сборки
- Добавил точку останова для каждого доступа к массиву, начал отладку (F5) и открыл окно Dissassembly
Итак, вот разборка для [i] = i; в 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
cmp / jb / call - проверка границ, фактически принудительное выполнение вызова вызывает исключение IndexOutOfRangeException.
То же самое для всех обращений к массиву, включая избыточный доступ в Test_SimpleRedundant. Так что-то не так с моей методологией тестирования, или CLR фактически не устраняет проверку границ? Надеюсь, я ошибаюсь, и если да, то мне хотелось бы узнать, как я могу получить проверки границ массивов.