2012-12-07 6 views
5

Zobacz poniższy kod, po prostu chcę, aby zrozumieć powód, że ...dlaczego CLR nie kompiluje przepełnienia const, ale dla zmiennych to robi?

const int a = 2147483647; 
const int b = 2147483647; 

int c = a + b; // it doesn't allow to compile!!! 

int a = 2147483647; 
int b = 2147483647; 

int c = a + b; // it allows to compile!!! 
+0

Po prostu przypuszczam, ale z pewnością dlatego, że są one stałe, a kompilator może stwierdzić, że po dodaniu * będą * przepełnione, podczas gdy ze zmienną traktuje wartości jako nieznane. – MadSkunk

+0

Nota boczna: CLR nie kompiluje kodu źródłowego C#, jest to kompilator C#. –

Odpowiedz

4

const wyrażenia są rozwiązywane w czasie kompilacji, nie- const wyrażenia są rozwiązywane przy starcie. Każda z nich ma domyślnie różne typy kontekstów kontroli przepełnienia. Zgodnie ze specyfikacją C#:

do wyrażenia non-stałych (wyrażeń, które są wyceniane w run-time), które nie są zamknięte w jakikolwiek zaznaczone lub odznaczone operatorów lub oświadczeń, kontekst sprawdzanie domyślny przelewowy jest zaznaczona , chyba że czynniki zewnętrzne (takie jak zmiana kompilatora i konfiguracja środowiska ) wymagają sprawdzenia.

Dlatego nie widzisz błędu runtime, gdy używasz zmiennych lokalnych do arytmetyki. Jak do obliczenia const:

dla wyrażeń stałych (wyrażenia, które mogą być w pełni ocenione w czasie kompilacji) domyślny przelewowy sprawdzanie kontekst jest zawsze sprawdzone. Jeśli nie podano stałego wyrażenia w niezebranionym kontekście, to przepełnienia, które wystąpią podczas analizy wyrażenia, zawsze powodują błędy podczas kompilacji.

Dlatego właśnie pojawia się błąd podczas kompilacji z obliczeniem const.

More information about checked and unchecked on MSDN.

0

ja przyjąć na siebie, bo wie, że compliler const nie mogą być modyfikowane tak a+b zawiedzie. Ale z innymi zmiennymi można je zmienić w czasie wykonywania, więc kompilator nie założy, że ustawione wartości nie zmienią się na prawidłową wartość.

2

W przypadku wartości stałych kompilator zasadniczo zastępuje zmienną stałą wartością w czasie kompilacji. Dlatego, gdy instrukcja addycji jest oceniana w czasie kompilacji, jest w stanie poznać wartości i zobaczyć warunek przepełnienia.

Dla zmiennych typu całkowitego nie sądzę, aby kompilator rzeczywiście uwzględniał przypisane wartości w czasie kompilacji, ale raczej obliczał wyrażenie w czasie wykonywania.

Ale C#, okazuje się, że kontrola jest domyślnie wyłączona. Możesz go włączyć w opcjach. Zobacz Justin Etheredge za doskonałą blogu na whys i jak to:

http://www.codethinked.com/c-trivia-what-no-overflow

+0

, ale nawet w środowisku wykonawczym nie wyrzuca wyjątku dla warunków przepełnienia – RollRoll

+0

Ha - masz rację! Zobacz moją edycję powyżej. –

Powiązane problemy