2012-02-16 8 views
5

Recentemente stavo leggendo this article da Dave Detlefs in cui presenta alcuni casi in cui CLR esegue i limiti dell'array per controllare l'eliminazione. Ho deciso di provare questo me stesso, così ho fatto la seguente:Limiti di array Controllare l'eliminazione nel CLR?

  • Inaugurato Visual Studio 2010 Ultimate SP1
  • Creato un nuovo C# progetto di tipo Applicazione console (puntando .NET 4 Client Profile per impostazione predefinita)
  • aggiunto il seguente codice (tutte le sub-modalità sono presi direttamente da questo articolo):

    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]; 
        } 
    } 
    
  • Switched alla modalità di rilascio; verificato che "ottimizzare il codice" è selezionata nelle opzioni di generazione

  • Aggiunto un punto di interruzione a ogni accesso agli array, iniziato il debug (F5) e ha aperto la finestra SMONTAGGIO

Quindi, ecco la lo smontaggio di un [i] = io; in 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/chiamata è controllo limiti, in realtà costringendo la chiamata da eseguire tiri un IndexOutOfRangeException.

Stessa cosa per tutti gli accessi di array, incluso l'accesso ridondante in Test_SimpleRedundant. Quindi c'è qualcosa di sbagliato nella mia metodologia di test, o il CLR in realtà non elimina il controllo dei limiti? Spero di sbagliarmi e, in tal caso, mi piacerebbe sapere come posso davvero ottenere i limiti dell'array controllando l'eliminazione.

+10

Quando si dice "debug avviato", presumo che si sia avviata l'applicazione * con il debugger allegato * dall'ambiente di Visual Studio. In tal caso, è necessario assicurarsi che la compilazione JIT sia abilitata perché non è predefinita. Il compilatore JIT è quello che esegue questa ottimizzazione, non il compilatore C#. –

+0

Cosa ti aspetti che accada se il controllo dei limiti è disabilitato? Questa è generalmente una caratteristica che le persone si aspettano di avere quando usano un linguaggio gestito come C#. –

+1

Il modo più semplice per garantire l'ottimizzazione è in realtà abilitato per avviare l'applicazione senza eseguire il debug e quindi collegare il debugger ad esso. – svick

risposta

12

Grazie ad un commento di Cody Grey, sono riuscito a rispondere alla mia domanda:

Per impostazione predefinita, ottimizzazioni JIT sono disattivati ​​durante il debug. Per risolvere questo problema, si può andare su Debug -> Opzioni e Impostazioni -> Debug -> Generale, e deselezionare entrambi "Abilita solo il mio codice" e "Sopprimi l'ottimizzazione JIT sul carico del modulo".

vedere anche http://msdn.microsoft.com/en-us/library/ms241594.aspx

Con l'ottimizzazione abilitata, i limiti di controllo vengono rimossi come pubblicizzato.

Lascerò questo qui per scopi di documentazione.

Problemi correlati