Różnica pomiędzy zmiennymi lokalnymi a automatycznymi.

0

Witam wszystkich serdecznie. Właśnie zaczytuje się w bardzo ciekawej lekturze, jaką jest symfonia C++ standard autorstwa Jerzego Grębosza i znalazłem pewną nieścisłość, czy też niedopowiedzenie, w tym, co ów autor napisał. Nie mogąc w Google znaleźć niczego, co rozwiałoby moje wątpliwości, postanowiłem napisać tutaj :)

No ale do rzeczy. W rozdziale 5 autor porusza m.in. zagadnienie zakresów ważności nazwy i czasu życia obiektów. Piszę on, iż zmienne lokalne, które są tworzone w ciele funkcji, to obiekty automatyczne, z czym się oczywiście zgadzam. Jak by nie było, są one tworzone tylko na potrzeby tej funkcji, na stosie, więc po opuszczeniu ciała funkcji, są one natychmiastowo likwidowane. Nie są one zerowane, tylko zawsze znajdują się w nich śmieci.

Pisze on również, że tylko obiekty globalne i lokalne statyczne są zerowane. Moje pytanie jest następujące: co z obiektami lokalnymi, tworzonymi np. w ciele funkcji main? Czy one również tworzone są na stosie (czyli są automatyczne)? Jakby nie było, ta funkcja ma pewne specjalne prawa (nigdzie jej nie definiujemy, nie można jej wywołać w z innej funkcji), a co najważniejsze, gdy napisałem taki krótki programik:

#include <iostream>
using namespace std;

int globalna;

inline void automatyczna(void)
{
  int automatyczna;
  cout << "Automatyczna wynosi = " << automatyczna << endl;
}
int main(int argc, char **argv) {
    int lokalna;
    cout << "Globalna wynosi = " << globalna << endl;
    cout << "Lokalna wynosi = " << lokalna << endl;
    automatyczna();
    return 0;
}
 

Okazało się, że ile razy bym go nie uruchomił, dla zmiennej globalnej, czego należało się spodziewać, wychodzi zero, dla automatycznej za każdym razem są to jakieś śmieci, a co do tej zmiennej, którą nazwałem lokalna, to o dziwo też wynik to zawsze 0. Ktoś potrafi mi to wytłumaczyć?

Z góry dziękuję za pomoc.

PS. Na samym końcu rozdziału jest zamieszczone pytanie kontrolne: "Mamy następujące obiekty: globalny, lokalny, automatyczny, statyczny. O których z nich można powiedzieć, że są wstępnie inicjalizowane zerami, o których, że zawierają śmieci, a o których, nic takiego nie można powiedzieć?", co pokazuje, że jednak jakaś różnica pomiędzy obiektami lokalnymi a automatycznymi jest, tylko jeszcze nie wiem jaka ^^

1

Wszystkie zmienne tworzone w taki sposób, które definiujesz wewnątrz jakiejś funkcji (czyli nie-globalne) i które nie są oznaczone jako static, są tworzone na stosie. Ergo mają losową wartość.
Funkcja main jest taką samą funkcją jak każda inna z tego punktu widzenia.

1

Co więcej, atrybut klasy może być wyzerowany ale nie musi, jeśli tę obiekt tej samej klasy utworzysz na stosie tak jak to zrobiłeś z automatyczną, to atrybut nie będzie zainicjowany.

W Visual C++ to od razu widać pod debug, bo zmienne nie zainicjowane mają taką dziwną wartość typu 0xCDCDCDCD czy coś w tym rodzaju.

Dlatego:

  • zmienne automatyczne inicjujesz przed użyciem (jest do tego warning)
  • atrybuty obiektu inicjujesz w konstruktorze
0

Czyli w takim wypadku można postawić znak równości pomiędzy zmiennymi lokalnymi a zmiennymi automatycznymi? A jeżeli tak, to dlaczego Grębosz jednak je rozróżnia, chociażby w tym pytaniu, o którym wspomniałem we wcześniejszym poście?

0

Wydaje mi się, że zmienna automatyczna w tym kontekście znaczy odwrotność zmiennej statycznej (stare znaczenie słowa kluczowego auto), przykładowo w funkcji:

 
void spam(){
    static int foo;
    /*auto*/ int bar; //zmienna lokalna jest domyślnie zmienną automatyczną
}

zmienna foo jest zmienną lokalną statyczną (min. zawierającą na starcie programu wartość zero), a bar zmienną lokalną automatyczną. Ogólnie rozdziałem na te typy bym się w ogóle nie przejmował, chyba, że masz z Gręboszem egzamin. Szczególnie, że zmiennych globalych (i statycznych pól klas) i statycznych rzadko się używa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1