B.3.3 Unchecked Union TypesPragma Unchecked_Union
pragma Unchecked_Union to
have the value True defines specifies an interface correspondence between a given discriminated type and some
C union. The aspect requires pragma
specifies that the associated type
shall be given a representation that leaves no space for its discriminant(s).]
For a discriminated record type having a variant_part,
the following language-defined representation aspect may be specified:
The type of aspect Unchecked_Union is Boolean.
If directly specified, the aspect_definition
shall be a static expression. If not specified (including by inheritance),
the aspect is False.
for Unchecked_Union: Type
is used to interface to a C union type.
4 and 5 were deleted.
is a representation pragma, specifying the unchecked union aspect of
type for to which aspect a
pragma Unchecked_Union is
True applies is called an unchecked union type. A subtype of an unchecked union
type is defined to be an unchecked union subtype. An object of
an unchecked union type is defined to be an unchecked union object.
All component subtypes of an unchecked union type
shall be C-compatible.
If a component subtype of an unchecked union type
is subject to a per-object constraint, then the component subtype shall
be an unchecked union subtype.
The type of a A component declared in a variant_part
of an unchecked union type shall not need
finalization. In addition to the places where Legality Rules normally
apply (see 12.3), this rule also applies in
the private part of an instance of a generic unit.
For an unchecked union type declared within the body of a generic unit,
or within the body of any of its descendant library units, no part of
the type of a component declared in a variant_part
of the unchecked union type shall be of a formal private type or formal
private extension declared within the formal part of the generic unit have
a controlled, protected, or task part.
The last part is a classic assume-the-worst rule
that avoids dependence on the actuals in a generic body. We did not include
this in the definition of “needs finalization” as it has
a bad interaction with the use of that term for the No_Nested_Finalization
An unchecked union subtype shall only be passed
as a generic actual parameter if the corresponding formal type has no
known discriminants or is an unchecked union type.
includes formal private types without a known_discriminant_part,
formal derived types that do not inherit any discriminants (formal derived
types do not have known_discriminant_parts),
and formal derived types that are unchecked union types.
An unchecked union type is eligible for convention
All objects of an unchecked union type have the
Discriminants of objects of an unchecked union
type are of size zero.
Any check which would require reading a discriminant
of an unchecked union object is suppressed (see 11.5).
These checks include:
The check performed when
addressing a variant component (i.e., a component that was declared in
a variant part) of an unchecked union object that the object has this
component (see 4.1.3).
Any checks associated with
a type or subtype conversion of a value of an unchecked union type (see
4.6). This includes, for example, the check
associated with the implicit subtype conversion of an assignment statement.
The subtype membership check
associated with the evaluation of a qualified expression (see 4.7)
or an uninitialized allocator (see 4.8).
a suppressed check would have failed, execution is erroneous (see 11.5).
An implementation is always allowed to make a suppressed check if it
can somehow determine the discriminant value.
A view of an unchecked union object (including
a type conversion or function call) has inferable discriminants
if it has a constrained nominal subtype, unless the object is a component
of an enclosing unchecked union object that is subject to a per-object
constraint and the enclosing object lacks inferable discriminants.
An expression of an unchecked union type has inferable
discriminants if it is either a name of an object with inferable discriminants
or a qualified expression whose subtype_mark
denotes a constrained subtype.
Evaluation of the predefined
equality operator for an unchecked union type if either of the operands
lacks inferable discriminants.
Evaluation of the predefined
equality operator for a type which has a subcomponent of an unchecked
union type whose nominal subtype is unconstrained.
Evaluation of a membership
test if the subtype_mark
denotes a constrained unchecked union subtype and the expression lacks
Conversion from a derived
unchecked union type to an unconstrained non-unchecked-union type if
the operand of the conversion lacks inferable discriminants.
Execution of the default
implementation of the Write or Read attribute of an unchecked union type.
Execution of the default
implementation of the Output or Input attribute of an unchecked union
type if the type lacks default discriminant values.
This paragraph was
implementation may require that pragma
Controlled be specified for the type of an access subcomponent of an
unchecked union type.
The use of an unchecked union to obtain the effect
of an unchecked conversion results in erroneous execution (see 11.5).
Execution of the following example is erroneous even if Float'Size =
type T (Flag : Boolean := False) is
case Flag is
when False =>
F1 : Float := 0.0;
when True =>
F2 : Integer := 0;
pragma Unchecked_Union (T);
X : T;
Y : Integer := X.F2; -- erroneous
Extensions to Ada 95
Incompatibilities With Ada 2005
Correction: The use
of discriminants on Unchecked_Union types is now illegal in record_representation_clauses,
as it makes no sense to specify a position for something that is not
supposed to exist. It is very unlikely that this change will have any
impact on existing code.
Extensions to Ada 2005
Aspect Unchecked_Union is new;
is now obsolescent.
Wording Changes from Ada 2005
Correction: Revised the rules to use the
“needs finalization” definition, and eliminated generic contract
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe