W tym rozdziale omówimy sytuacje, kiedy lokalna zmienna może nie być widoczna dla programu. Takim pierwszym oczywistym przypadkiem jest błąd w kodzie źródłowym, kiedy najpierw program musi skorzystać ze zmiennej, a dopiero potem ta zmienna jest tworzona (kod 1).
#property strict
void OnStart()
{
Print("LocalVariable = ",LocalVariable); /* błąd,
kompilator nie widzi
LocalVariable */
int LocalVariable = 7;
}
Tutaj niedoświadczony programista chciałby, aby najpierw została wyświetlona wartość nie istniejącej zmiennej LocalVariable, a dopiero potem została by ona utworzona. Kompilator wyświetli błąd: 'LocalVariable' - undeclared identifier, tj. 'LocalVariable' - nie zadeklarowany identyfikator. Te dwie instrukcje należy zamienić miejscami i problem zniknie.
Taki sam problem będzie miał miejsce jeśli wewnątrz jednego obszaru lokalnego zostanie utworzony drugi. W tym drugim obszarze program będzie musiał skorzystać ze zmiennej, która jednak zostanie utworzona później w pierwszym obszarze (kod 2).
#property strict
void OnStart()
{
bool LocalFlag = true;
//--- granica obszaru lokalnego 'if', początek
if(LocalFlag == true) // ok, kompilator widzi LocalFlag
{
Print("LocalVariable = ",LocalVariable); /* błąd,
kompilator nie widzi
LocalVariable */
}
//--- granica obszaru lokalnego 'if', koniec
int LocalVariable = 7;
}
W tym kodzie w obszarze OnStart() najpierw następuje inicjalizacja zmiennej LocalFlag. Następnie operator if musi zobaczyć LocalFlag, aby móc sprawdzić warunek zapisany w jego nagłówku. W naszym przypadku jest ok, ponieważ zmienna ta została wcześniej zainicjowana. Dalej w obszarze utworzonym przez if za pomocą Print() program musi wyświetlić wartość nieistniejącej jeszcze w tym momencie zmiennej LocalVariable. Nieistniejącej, dlatego że jej inicjalizacja nastąpi dopiero później. Dla tego kodu kompilator wyświetli błąd: 'LocalVariable' - undeclared identifier, tj. 'LocalVariable' - nie zadeklarowany identyfikator.
Aby wyeliminować ten błąd zmienną LocalVariable należy zainicjalizować albo przed Print() w granicach if (kod 3) albo w obszarze OnStart() przed if (kod 4).
#property strict
void OnStart()
{
bool LocalFlag = true;
if(LocalFlag == true)
{
int LocalVariable = 7;
Print("LocalVariable = ",LocalVariable); /* ok,
kompilator widzi
LocalVariable */
}
}
#property strict
void OnStart()
{
bool LocalFlag = true;
int LocalVariable = 7;
if(LocalFlag == true)
{
Print("LocalVariable = ",LocalVariable); /* ok,
kompilator widzi
LocalVariable */
}
}
Omówmy kolejną sytuację, kiedy może wystąpić problem z widocznością zmiennej. Programista przygotował kod, gdzie inicjalizację zmiennej napisał przed jej wykorzystaniem (kod 5) i mogłoby się wydawać, że powinno być dobrze ale ... .
#property strict
void OnStart()
{
bool LocalFlag = true;
//--- granica obszaru lokalnego 'if', początek
if(LocalFlag == true)
{
int LocalVariable = 7;
}
//--- granica obszaru lokalnego 'if', koniec
Print("LocalVariable = ",LocalVariable); /* błąd,
kompilator nie widzi
LocalVariable */
}
Dla tego kodu kompilator wyświetli taki samy błąd jak i w przypadku kodów 1 i 2: 'LocalVariable' - undeclared identifier, tj. 'LocalVariable' - nie zadeklarowany identyfikator. Stanie się to tak dlatego, że ta zmienna została zainicjalizowana w obszarze utworzonym przez if i tylko tam jest ona dostępna dla programu.
Wytłumaczenie jest następujące. W momencie kiedy program dochodzi do operatora if i widzi, że warunek w jego nagłówku jest prawdziwy, to program tworzy nowy obszar lokalny. Dokonuje w nim inicjalizacji zmiennej LocalVariable, tj. w pamięci RAM rezerwuje miejsce i zapisuje tam wartość 7. Kiedy program dochodzi do końca tego obszaru, tj. do zamykającej klamry }, program niszczy ten obszar a wraz z nim i wszystkie zmienne tam utworzone. W naszym przypadku wychodząc z obszaru if z RAM usuwana jest LocalVariable i dlatego, kiedy program idzie do Print(), tj. wraca do poprzedniego obszaru OnStart(), ta zmienna już nie istnieje. Mówiąc inaczej czas życia zmiennej jest ograniczony czasem życia obszaru, gdzie została ona utworzona.