2009-12-25 5 views
1
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); 
    } 
} 

retourne vraiment 45.
pourquoi ne pas jeter des exceptions?comment cela peut-il arriver?

Répondre

6

Pourquoi vous attendez-vous à ce qu'il lève une exception?

Par défaut, le code C# est unchecked, ce qui signifie que les débordements et autres sont simplement ignorés silencieusement. Vous pouvez trouver vos paramètres de projet actuels pour ce paramètre en allant dans les propriétés du projet, onglet Construire, et en cliquant sur le bouton Avancé dans le contenu de l'onglet. Dans la boîte de dialogue qui apparaît, vous devriez avoir un "Vérifier le dépassement/dépassement arithmétique". Ce paramètre est désactivé par défaut.

Dans ce cas, vous incrémentez le premier octet de la valeur int x de 32 bits (4 octets) en passant un pointeur en tant que c et vous l'incrémentez 300 fois.

Cela l'incrémente 256 fois, ce qui le ramène à 0, puis à 44 fois. Depuis qu'il a commencé à 1, il est maintenant 45.

Vous pouvez facilement tester en exécutant le code suivant:

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

Vous obtiendrez:

b = 0

pas une exception de débordement. Cela dit, vous ne devriez probablement pas utiliser de pointeurs et de code dangereux jusqu'à ce que vous en ayez réellement besoin.

+0

"Par défaut, le code C# n'est pas coché." Je ne le savais vraiment pas. – Behrooz