Jestem nowy w Delphi i przeprowadziłem kilka testów, aby zobaczyć, jakie zmienne obiektu i zmienne stosu są domyślnie inicjowane:
TInstanceVariables = class
fBoolean: boolean; // always starts off as false
fInteger: integer; // always starts off as zero
fObject: TObject; // always starts off as nil
end;
Do takiego zachowania jestem przyzwyczajony w innych językach, ale zastanawiam się, czy można na nim bezpiecznie polegać w Delphi? Na przykład zastanawiam się, czy może to zależeć od ustawień kompilatora, czy może działać inaczej na różnych komputerach. Czy normalne jest poleganie na domyślnych zainicjowanych wartościach obiektów, czy też jawnie ustawiasz wszystkie zmienne instancji w konstruktorze?
Jeśli chodzi o zmienne stosu (na poziomie procedury), moje testy pokazują, że zjednolicone wartości logiczne są prawdziwe, zjednostkowane liczby całkowite to 2129993264, a niezinicjalizowane obiekty są po prostu nieprawidłowymi wskaźnikami (tj. Nie są zerowe). Domyślam się, że normą jest zawsze ustawianie zmiennych na poziomie procedury przed uzyskaniem do nich dostępu?
Odpowiedzi:
Tak, to jest udokumentowane zachowanie:
Pola obiektów są zawsze inicjalizowane na 0, 0,0, '', False, nil lub cokolwiek ma zastosowanie.
Zmienne globalne są również zawsze inicjalizowane na 0 itd .;
Lokalne zmienne liczone jako referencje * są zawsze inicjalizowane na zero lub '';
Zmienne lokalne nie liczone jako odwołania * nie są zainicjowane, więc przed użyciem należy przypisać wartość.
Pamiętam, że Barry Kelly napisał gdzieś definicję „zliczonych referencji”, ale nie mogę jej już znaleźć, więc w międzyczasie powinno wystarczyć:
Uwagi:
record
samo w sobie nie wystarczy, aby zostać zaliczonym do referencjiźródło
TObject.Create
, co jest metodą void, ale wclass function TObject.InitInstance(Instance: Pointer): TObject;
której jest ZAWSZE wywoływana przed jakimkolwiek wywołaniem konstruktora, nawet w przypadku starszych wersji Delphi. Twój komentarz jest błędny i mylący IMHO.Zmienne globalne, które nie mają jawnego inicjatora, są przydzielane w sekcji BSS w pliku wykonywalnym. W rzeczywistości nie zajmują miejsca w pliku EXE; sekcja BSS jest specjalną sekcją, którą system operacyjny przydziela i czyści do zera. W innych systemach operacyjnych istnieją podobne mechanizmy.
Możesz polegać na inicjalizacji zmiennych globalnych.
źródło
Pola klas mają domyślnie zero. Jest to udokumentowane, więc możesz na nim polegać. Zmienne stosu lokalnego są niezdefiniowane, chyba że łańcuch lub interfejs, są ustawione na zero.
źródło
Na marginesie (ponieważ jesteś nowy w Delphi): Zmienne globalne można zainicjować bezpośrednio podczas ich deklarowania:
źródło
Oto cytat z Raya Lischners Delphi w pigułce Rozdział 2
Prawdą jest, że zmienne lokalne w zakresie muszą zostać zainicjalizowane… Powyższy komentarz, że „Zmienne globalne są inicjalizowane”, traktowałbym jako wątpliwy, dopóki nie otrzymam odniesienia - nie wierzę w to.
edytuj ... Barry Kelly mówi, że możesz polegać na ich inicjalizacji zerowej, a ponieważ jest w zespole kompilatorów Delphi, wierzę, że tak jest :) Dzięki Barry.
źródło
Zmienne globalne i dane (pola) instancji obiektu są zawsze inicjowane na zero. Zmienne lokalne w procedurach i metodach nie są inicjowane w Win32 Delphi; ich zawartość jest niezdefiniowana, dopóki nie przypiszesz im wartości w kodzie.
źródło
Nawet jeśli język oferuje domyślne inicjalizacje, uważam, że nie należy na nich polegać. Inicjalizacja do wartości sprawia, że jest ona znacznie bardziej przejrzysta dla innych programistów, którzy mogą nie wiedzieć o domyślnych inicjalizacjach w języku, i zapobiega problemom między kompilatorami.
źródło
Z pliku pomocy Delphi 2007:
ms-help: //borland.bds5/devcommon/variables_xml.html
źródło
Mam mały problem z udzielonymi odpowiedziami. Delphi zeruje przestrzeń pamięci globali i nowo utworzonych obiektów. Chociaż to NORMALNIE oznacza, że są zainicjowane, jest jeden przypadek, w którym tak nie jest: typy wyliczeniowe z określonymi wartościami. A jeśli zero nie jest wartością prawną?
źródło
TOneTwoThree = (One=1, Two=2, Three=3);
Nowo wprowadzone (od Delphi 10.3) zmienne wbudowane ułatwiają kontrolę wartości początkowych.
źródło