Rationale for Ada 2012

John Barnes
Contents   Index   References   Search   Previous   Next 

7.6 Miscellanea

The first item is that the package Stream_IO should be marked as preelaborated. So in Ada 2012 it now begins
with Ada.IO_Exceptions;
package Ada.Streams.Stream_IO isis
   pragma Preelaborate(Stream_IO);
The reason for making this change concerns the use of input—output in preelaborated packages. The normal input—output packages such as Text_IO are not preelaborated and so cannot be used in packages that are themselves preelaborated. This makes preelaborated packages awkward to debug since they cannot do straightforward output for monitoring purposes. To make packages such as Text_IO preelaborated is essentially impossible because they involve local state. However, no such problem exists with Stream_IO, and so making it preelaborated means that it can be used to implement simple logging facilities in other preelaborated packages.
In principle, there is a similar problem with pure units. But they cannot change state anyway and so cannot do output since that changes the state of the environment. They just have to be written correctly in the first place.
(I have been told that there are naughty ways around this with pure packages but I will not contaminate innocent minds with the details.)
The package Ada.Environment_Variables was introduced in Ada 2005 as follows
package Ada.Environment_Variables is
   pragma Preelaborate(Environment_Variables);
   function Value(Name: String) return String;
   function Exists(Name: String) return Boolean;
   procedure Set(Name: in String; Value: in String);
   procedure Clear(Name: in String);
   procedure Clear;
   procedure Iterate(Process: not null access procedure
      (Name, Value: in String));
end Ada.Environment_Variables;
If we do not know whether an environment variable exists then we can check by calling Exists prior to accessing the current value. Thus a program might be running in an environment where we might expect an environment variable "Ada" whose value indicates the version of Ada currently supported.
So as in [7] we might write
if not Exists("Ada") then
   raise Horror;
end if;
Put("Current Ada is "); Put_Line(Value("Ada"));
But this raises a possible race condition. After determining that Ada does exist some malevolent process (such as another Ada task or an external human agent) might execute Clear("Ada"); and then the call of Value("Ada") will raise Constraint_Error.
The other race condition might arise as well. Having decided that Ada does not exist and so taking remedial action some kindly process might have created Ada.
These problems are overcome in Ada 2012 by the introduction of an additional function Value with a default parameter
function Value(Name: String; Default: String);
Calling this version of Value returns the value of the variable if it exists and otherwise returns the value of Default.

Contents   Index   References   Search   Previous   Next 
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by:
The Ada Resource Association:


and   Ada-Europe: