2016-06-13 30 views
21

Mówiąc z kolegą z kopalni, mówili, że:Czy uzyskujesz dostęp do statycznego poza zakresem niezdefiniowanego zachowania?

foo() { 
    int *p; 
    { 
     int x = 5; 
     p = &x; 
    } 
    int y = *p; 
} 

tworzy niezdefiniowanej zachowanie, ponieważ żywotność zasady i reguły zakres nie nie określił.

Jednakże:

foo() { 
    int *p; 
    { 
     static int x = 5; 
     p = &x; 
    } 
    int y = *p; 
} 

nie jest niezdefiniowany! Kończy się problemami "pośredniego zakresu".

Używanie terminologii nie brzmi poprawnie.
Wiem, że statyczne nie ma nic wspólnego z określaniem zakresu.
Czy prawdą jest, że drugi przypadek ma określone zachowanie?

+0

Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została [przeniesiona na czat] (http://chat.stackoverflow.com/rooms/114724/discussion-on-on---rerevor-hickey-jest-dostępem-a-statycznym-w-suku-skasie- undef). –

Odpowiedz

31

Tak, drugi przypadek ma dobrze zdefiniowane zachowanie. Zmienna static jest po prostu zmienną globalną, której nazwa jest określona w zakresie, w którym została zadeklarowana. Jest inicjowana przy pierwszym wprowadzeniu zakresu, a następnie pozostaje aktywna przez cały czas działania programu.

Więc kiedy dotrzemy

int y = *p; 

p punkty do zmiennej, która nie będzie można osiągnąć (nie można wrócić do tego kodu), ale wciąż ma ważny przez całe życie.

Cytując standardowe [basic.stc.static]

Wszystkie zmienne, które nie mają dynamiczny okres przechowywania, nie mają czas przechowywania nici, a nie są lokalne mają statyczny czas przechowywania. Przechowywanie tych podmiotów powinny trwać przez cały czas trwania programu

podkr

Pierwszy przypadek jest zdefiniowana jako życia lokalnego zakresu x kończy na } i próbuje zwrócić do niego po jego końcach życia jest niezdefiniowane zachowanie.

+0

W drugim przypadku jest '* p = 42;' undefined? –

+3

@sunqingyao: W porządku, dlaczego by nie było? C nie wymaga, aby lokalizacje magazynowe miały nazwy. W przeciwnym razie 'malloc' byłby bezużyteczny. – rici

1

cytując here

statycznej klasy pamięci instruuje kompilator, aby utrzymać zmienną lokalną w istnieniu w czasie życia czasie programu zamiast tworzenia i niszczenia go za każdym razem, gdy przychodzi do i wychodzi zakresu. Dlatego ustawienie zmiennych lokalnych na statyczne pozwala im zachować swoje wartości między wywołaniami funkcji.

tak tak w drugim przypadku x istnieje podczas całego okresu istnienia programu.

dlatego ma zdefiniowane zachowanie.

+1

Co cytujesz? – Barry

+0

Istnieje różnica między pamięcią statyczną a specyfikatorem 'static' _storage-class ** ** _. – Olaf

+0

@Olaf Czy możesz podać kilka linków dotyczących różnicy między statyczną pamięcią masową a specyfikatorem klasy pamięci, więc będzie mi lepiej zrozumieć to lepiej? – mssirvi