So far, we have assumed that the entire program is either compiled using the dynamic model or static model, ensuring consistency. It is possible to mix the two models, but rules have to be followed if this mixing is done to ensure that elaboration checks are not omitted.
The basic rule is that `a unit compiled with the static model cannot be |withed| by a unit compiled with the dynamic model'. The reason for this is that in the static model, a unit assumes that its clients guarantee to use (the equivalent of) pragma Elaborate_All so that no elaboration checks are required in inner subprograms, and this assumption is violated if the client is compiled with dynamic checks.
The precise rule is as follows. A unit that is compiled with dynamic checks can only `with' a unit that meets at least one of the following criteria:
If this rule is violated, that is if a unit with dynamic elaboration checks `with's a unit that does not meet one of the above four criteria, then the binder (gnatbind) will issue a warning similar to that in the following example:
warning: "x.ads" has dynamic elaboration checks and with's warning: "y.ads" which has static elaboration checks
These warnings indicate that the rule has been violated, and that as a result elaboration checks may be missed in the resulting executable file. This warning may be suppressed using the `-ws' binder switch in the usual manner.
One useful application of this mixing rule is in the case of a subsystem which does not itself `with' units from the remainder of the application. In this case, the entire subsystem can be compiled with dynamic checks to resolve a circularity in the subsystem, while allowing the main application that uses this subsystem to be compiled using the more reliable default static model.