2012-02-16 2 views
5

Я недавно читал 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 на самом деле не устраняет проверку границ? Надеюсь, я ошибаюсь, и если так, я хотел бы знать, как я могу действительно получить проверку границ массива.

+10

Когда вы говорите «начатая отладка», я предполагаю, что вы запустили приложение * с прикрепленным отладчиком * из среды Visual Studio. В этом случае вам нужно убедиться, что компиляция JIT включена, потому что она не по умолчанию. Компилятор JIT - это тот, который выполняет эту оптимизацию, а не компилятор C#. –

+0

Что вы ожидаете, если проверка границ отключена? Обычно это функция, которую люди ожидают иметь при использовании управляемого языка, такого как C#. –

+1

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

ответ

12

Благодаря замечание Коди Грей, что мне удалось ответить на мой собственный вопрос:

По умолчанию JIT Оптимизации отключены при отладке. Чтобы исправить это, можно перейти в Debug -> Options and Settings -> Debugging -> General и снять флажок «Включить только мой код» и «Подавить оптимизацию JIT при загрузке модуля».

http://msdn.microsoft.com/en-us/library/ms241594.aspx Также см

С оптимизацией включена, границы чек удаляются как рекламируется.

Я оставлю это здесь для целей документации.