Rationale for Ada 2012
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.
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by: