There are scenarios in which your programs may
use low level techniques to modify variables
that otherwise might be considered to be unassigned. For example,
you can pass a variable to a procedure by reference by taking
the address of the parameter and using that address to modify the
variable’s value, even though the address is passed as an in
parameter.
Consider the following example:
procedure P is Max_Length : constant Natural := 16; type Char_Ptr is access all Character; procedure Get_String(Buffer: Char_Ptr; Size : Integer); pragma Import (C, Get_String, "get_string"); Name : aliased String (1 .. Max_Length) := (others => ' '); Temp : Char_Ptr; function Addr (S : String) return Char_Ptr is function To_Char_Ptr is new Ada.Unchecked_Conversion (System.Address, Char_Ptr); begin return To_Char_Ptr (S (S'First)'Address); end; begin Temp := Addr (Name); Get_String (Temp, Max_Length); end;
where Get_String is a C function that uses the address in Temp
to
modify the variable Name
. This code is dubious, and arguably
erroneous, and the compiler is entitled to assume that
Name
is never modified, and generate code accordingly.
However, in practice, this could cause some existing code that seems to work with no optimization to start failing at higher levels of optimization.
What the compiler does for such cases, is to assume that marking a
variable as aliased indicates that some “funny business” may be going
on. The optimizer recognizes the aliased
keyword and inhibits any
optimizations that assume the variable cannot be assigned to. This
means that the above example will in fact “work” reliably, that is, it
will produce the expected results. However, you should nevertheless
avoid code such as this if possible because it’s not portable and may not
functin as you expect with all compilers.