AdaVirtus

 
  • Increase font size
  • Default font size
  • Decrease font size

Perełka #2: Typy ograniczone w Adzie 2005 — Notacja ‹› w agregatach

Autor: Bob Duff, AdaCore

Temat: Perełka Ady #2 — Notacja <> może być wykorzystana w agregatach to uzyskania domniemanej wartości poszczególnych składowych.

Zaczynamy ...

Z poprzedniej perełki wiemy już, że Ada 2005 zezwala na agregaty w przypadku typów ograniczonych. Taki agregat musi być użyty do inicjalizacji pewnych obiektów (wśród których mamy przekazywanie parametrów, w którym to przypadku inicjalizujemy parametry formalne). Agregaty ograniczone mają cechę "wbudowane w miejscu" w obiekcie będącym inicjalizowanym.

Oto przykład:

type Limited_Person is limited
   record
      Self : Limited_Person_Access := Limited_Person'Unchecked_Access;
      Name : Unbounded_String;
      Age : Natural;
      Shoe_Size : Positive;
   end record;
 
X : aliased Limited_Person :=
      (Self => null,                   -- Źle!
 
       Name => To_Unbounded_String (”John Doe”),
       Age => 25,
       Shoe_Size => 10);
X.Self := X’Access;

Jest dosyć niewygodnym ustalać wartość Self na wartość złą (null), a następnie poprawianie tego. Irytującym jest również, że mamy (poprawną) domniemaną wartość dla Self, lecz w Adzie 95 nie możemy używać w agregatach wartości domniemanych. Ada 2005 wzbogaca składnię agregatów - "<>" oznacza: "skorzystaj z wartości domniemanej, jeśli takowa jest".

Teraz możemy zapisać:

X : aliased Limited_Person :=
      (Self => <>
       Name => To_Unbounded_String (”John Doe”),
       Age => 25,
       Shoe_Size => 10)

Zapis "Self => <>" oznacza wykorzystanie wartości domniemanej Limited_Person'Unchecked_Access. Ponieważ Limited_Person pojawia się wewnątrz deklaracji typu, Self odwołuje się do "bieżącej instacji" typu, w naszym przypadku do X. Tak więc, ustalamy wartość X.Self na X'Unchecked_Access.

Notacja wykorzystująca zapis "<>" w agregatach może być niebezpieczna, gdyż może pozostawić pewne składowe niezainicjowane. "<>" oznacza: "wykorzystaj wartość domniemaną". Jeśli typ składowej jest skalarem i brak jest wartości domniemanej składowej rekordu, to wartość składowej pozostaje nieustalona.

Dla przykładu, jeśli mamy agregat typu String jak poniżej:

Uninitialized_String_Const : constant String := (1 .. 10 => <>);
 

otrzymujemy 10 znakowy łańcuch, którego wszystkie znaki mają nieprawidłową wartość. Zwróćmy uwagę, że jest to równie niebezpieczne jak:

Uninitialized_String_Var : String (1 .. 10);    -- brak inicjalizacji
Uninitialized_String_Const : constant String := Uninitialized_String_Var;

Wniosek: należy być bardzo ostrożnym w przypadku niezainicjowanych obiektów skalarnych.

Zmieniony: Sobota, 28 Listopad 2009 22:18  

Dodaj swój komentarz

Imię:
Temat:
Komentarz: