Controlling elaboration order when Ada.Real_Time package is used

I was reading the Guide for the use of the Ada Ravenscar Profile in high integrity systems, in particular the specification of Activation_Manager package at page 67.

with Ada.Real_Time;

package Activation_Manager is

 use Ada.Real_Time;

 function Clock return Ada.Real_Time.Time renames Ada.Real_Time.Clock;

 -- global start time relative to which all periodic events
 -- in system will be scheduled
 System_Start_Time : Ada.Real_Time.Time : constant := Clock;

 -- relative offset of task activation after elaboration (milliseconds)
 Relative_Offset : constant Natural := 100;

 Task_Start_Time : constant Ada.Real_Time.Time_Span :=
 Ada.Real_Time.Milliseconds(Relative_Offset);

 -- absolute time for synchronization of task activation after elaboration
 Activation_Time : constant Ada.Real_Time.Time :=
System_Start_Time + Task_Start_Time;

 procedure Activation_Sporadic;

 procedure Activation_Cyclic
 (Next_Time : out Ada.Real_Time.Time);

end Activation_Manager;

In order to avoid any access-before-elaboration (ABE) error, shouldn’t be the case to control the elaboration of Ada.Real_Time body using pragma Elaborate (Ada.Real_Time);? In this way, the previous spec should be:

with Ada.Real_Time;
pragma Elaborate (Ada.Real_Time);

package Activation_Manager is

 use Ada.Real_Time;

 function Clock return Ada.Real_Time.Time renames Ada.Real_Time.Clock;

 -- global start time relative to which all periodic events
 -- in system will be scheduled
 System_Start_Time : Ada.Real_Time.Time : constant := Clock;

 ... and so on ...

end Activation_Manager;

I think that pragma is needed since the use of Clock function belonging to Ada.Real_Time package. It looks like the scenario described here:

Isn’t it? Is this different because we’re talking about a dependency on a runtime package rather than an application one?

Manual elaboration control is rare used feature now, at least in case of GNAT. Access before elaboration is almost impossible in regular Ada code.

We have some good elaboration algorithms now.
It’s best to let the compiler handle them unless/until you need to actually specify. It’s like saying Type This is range 0..255 with Size => 16; — unless there’s a reason to specify the size (like low-level layouts), it’s best to let the compiler make the choice.

You’re right, there is no pragma Preelaborate.
However, if you are using Gnat, it has a special elaboration routine different from the one of the RM (you can get the latter with a compiler switch, -E perhaps), so it’s improbable that you’ll run into elaboration problems.
In any case, inclusion of this pragma will not impede your code. And for true portability, it’s good advice to include it.

Thanks for your answers. I think @Nordic_Dogsledding got the point about compiler portability. I understand that it’s unlikely for an ABE to occur these days, but this assumption is based on the use of recent versions of GNAT. It’s not unlikely that, especially on safety-critical jobs, you might use outdated Ada compilers or ones other than GNAT.

I compile most things with both GNAT and ObjectAda, and have never had an elaboration issue with ObjectAda with code that does not specify elaboration order.

I think that concerns are a bit misguided. In my experience GNAT rather indicates elaboration problems than attempts to work them around. Long ago there were some false positives and elaboration pragmas helped GNAT to come through. Now, as it was already pointed out, GNAT does not need that help anymore, so I stopped using elaboration pragmas.

The only real problems with elaboration I ever had were upon dynamic loading relocatable libraries. But these are totally different problems.