6.3.1.10 Aliased Variables and Optimization

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.