2010-07-16 7 views
6

Warum in C# ist Beispiel A gültig, kompilierbar und wird nur umbrochen, während Beispiele B nicht kompilieren?arithmetische Ausnahme in C#

A

int val = 0; 
val = val + Int32.MaxValue +2; 

oder

int val = Int32.MaxValue; 
val++; 

B

int val = 0; 
val = 2147483647 + 1; 

oder

int val = 0; 
int val = Int32.MaxValue + 1; 

Ich weiß, Diese arithmetischen Ausnahmen werden standardmäßig nicht standardmäßig überprüft, es sei denn, Sie verwenden explizit die überprüfte Methode, Block oder Attribut in der Konfiguration. Meine Frage bezieht sich mehr auf den Compiler als auf eine arithmetische Ausnahme.

+1

Ich glaube, Sie haben etwas vermisst, während Sie eine Frage stellen. Was ist nach "Meine Frage bezieht sich mehr auf __________"? – bits

+0

@bits ja ich tat cheers –

Antwort

16

Ihre B-Beispiele sind constant-folded zur Kompilierzeit und geben dem Compiler an, dass ein Überlauf garantiert ist.

Da Ihre A-Beispiele Variablen verwenden, können die Ausdrücke nicht (vollständig) konstant gefaltet werden, sodass der Compiler nicht garantieren kann, dass die Werte zu einem Überlauf führen.

Zum Beispiel ...

int val = 0; 
// some other thread changes `val` to -5... 
val = val + Int32.MaxValue +2; // no overflow 

Wenn Sie jedoch dass val und weisen 0 auf einen const int ändern wird nicht wissen, :

const int startval = 0; 
int val = startval + Int32.MaxValue + 2; 

können Sie Ihre compile- erhalten Zeitüberlauf zurück überprüfen, da der Wert vollständig ermittelt und daher konstant gefaltet werden kann.

1

Es hat einfach mit den Einschränkungen der Überprüfung der Kompilierzeit zu tun. Bestimmte Dinge können nur zur Laufzeit bekannt sein.

3

Ich weiß, dass arithmetische Ausnahmen sind nicht standardmäßig aktiviert, wenn Sie explizit so Methode, Block oder ein Attribut in der Konfigurations

Sie wissen nicht, überprüfen nicht verwenden, weil diese Aussage ist falsch. Und tatsächlich wissen Sie, dass es falsch ist, weil Sie einen Fall angegeben haben, in dem Ihre Aussage als falsch bewiesen wurde!

verweise ich Sie auf Abschnitt 7.6.12 der C# Spezifikation, ein Teil von dem ich hier für Sie reproduzieren:

Für nicht konstante Ausdrücke (Ausdrücke, die zur Laufzeit ausgewertet werden), dass Wenn diese Option nicht von überprüften oder nicht aktivierten Operatoren oder Anweisungen eingeschlossen ist, wird der Standardkonfliktüberprüfungskontext deaktiviert, es sei denn, externe Faktoren (z. B. Compilerschalter und Ausführungsumgebungskonfiguration) erfordern eine Überprüfung der Überprüfung.

Für konstante Ausdrücke (Ausdrücke, die zur Kompilierzeit vollständig ausgewertet werden können) wird der Standardüberlaufüberprüfungskontext immer überprüft.Wenn ein konstanter Ausdruck nicht explizit in einen ungeprüften Kontext platziert wird, verursachen Überläufe, die während der Kompilierungszeitauswertung des Ausdrucks auftreten, immer Kompilierungsfehler.

Weitere Details finden Sie in der Spezifikation.

+0

Fair Genug, dass die Aussage sollte "zur Laufzeit" sagen –