13.9.2 The Valid Attribute
The Valid attribute can be used to check the validity
of data produced by unchecked conversion, input, interface to foreign
languages, and the like.
Static Semantics
For a
prefix
X that denotes a scalar object [(after any implicit dereference)], the
following attribute is defined:
X'Valid
{
AI05-0153-3}
{
AI12-0071-1}
Yields True if and only if the object denoted by X is normal, has a valid
representation, and then, if the preceding conditions hold, the value
of X also satisfies the predicates
of the nominal
subtype of X. The value of this attribute is of the predefined type Boolean.
Ramification: Having checked that X'Valid
is True, it is safe to read the value of X without fear of erroneous
execution caused by abnormality, or a bounded error caused by an invalid
representation. Such a read will produce a value in the subtype of X.
{
AI22-0115-1}
Notwithstanding what this Reference Manual says
elsewhere, evaluating X'Valid does not evaluate the prefix X unless X
is normal and has a valid representation. If X is Volatile, evaluating
X'Valid is still considered a read of X.
Reason: Evaluating
the prefix X for an invalid or abnormal value would trigger a bounded
error or erroneous execution, thus defeating the purpose of the attribute.
Since an implementation
is not allowed to add, remove, or reorder accesses to volatile objects,
we have to define X'Valid as a read so that it is implementable for most
subtypes as the value of the object is required.
Ramification: A
“read of X” in the sense of C.6
does not imply the evaluation of X; the second sentence of the wording
does not change the first. The implementation of XValid has to
retrieve the value of X so it can be tested for validity (regardless
of volatility), so all were doing here is making that explicit
in the case of a volatile object.
Usage
{
AI22-0055-1}
The Valid attribute can be used to check the result
of calling an instance of Unchecked_Conversion (or any other operation
that can return invalid values). However, an exception handler should
also be provided because implementations are permitted to raise Constraint_Error
or Program_Error if they detect the use of an invalid representation
(see 13.9.1).
NOTE 1 Invalid
data can be created in the following cases (not counting erroneous or
unpredictable execution):
an uninitialized scalar object,
the result of an unchecked conversion,
input,
interface to another language (including
machine code),
aborting an assignment,
disrupting an assignment due to the
failure of a language-defined check (see
11.6),
and
use of an object whose Address has
been specified.
NOTE 2 {
AI12-0071-1}
{
AI12-0440-1}
{
AI22-0115-1}
Since evaluating X'Valid does not evaluate X unless
X is normal and valid Determining whether
X is normal and has a valid representation as part of the evaluation
of X'Valid is not considered to include an evaluation of X; hence,
it is not an error to check the validity of an object that is invalid
or abnormal. Determining whether X satisfies the predicates of its nominal
subtype can include an evaluation of X, but
this
determination is made only after it has been determined that X
has a valid representation
and therefore is safe
to evaluate.
This paragraph was
deleted.{
AI12-0071-1}
{
AI22-0115-1}
If X is volatile, the evaluation of X'Valid is
considered a read of X.
This paragraph
was deleted.Reason: Since an
implementation is not allowed to add, remove, or reorder accesses to
volatile objects, we have to define X'Valid as a read so that it is implementable
for most subtypes as the value of the object is required.
This paragraph was
deleted.NOTE 3 {
AI95-00426-01}
{
AI12-0442-1}
{
AI22-0055-1}
The Valid attribute can be used to check the result
of calling an instance of Unchecked_Conversion (or any other operation
that can return invalid values). However, an exception handler is still
useful because implementations are permitted to raise Constraint_Error
or Program_Error if they detect the use of an invalid representation
(see 13.9.1).
Ramification: If X is of an enumeration
type with a representation clause, then X'Valid checks that the value
of X when viewed as an integer is one of the specified internal codes.
Reason: Valid is defined only for scalar
objects because the implementation and description burden would be too
high for other types. For example, given a typical run-time model, it
is impossible to check the validity of an access value. The same applies
to composite types implemented with internal pointers. One can check
the validity of a composite object by checking the validity of each of
its scalar subcomponents. The user should ensure that any composite types
that need to be checked for validity are represented in a way that does
not involve implementation-defined components, or gaps between components.
Furthermore, such types should not contain access subcomponents.
Extensions to Ada 83
X'Valid is new in Ada 95.
Wording Changes from Ada 95
{
AI95-00426-01}
Added a note explaining that handlers for Constraint_Error and Program_Error
are needed in the general case of testing for validity. (An implementation
could document cases where these are not necessary, but there is no language
requirement.)
Wording Changes from Ada 2005
{
AI05-0153-3}
The validity check now also includes a check of the predicate aspects
(see
3.2.4), if any, of the subtype of the
object.
Wording Changes from Ada 2012
{
AI12-0071-1}
Corrigendum: Updated wording of the attributes X'Valid to use
the new term "satisfies the predicates" (see
3.2.4).
Also updated the notes to make sense when evaluating predicates and testing
validity of volatile objects.
Wording Changes from Ada 2022
{
AI22-0115-1}
Corrigendum: We now normatively say that
the prefix of X'Valid is not evaluated until after we've checked for
validity, because that cannot be derived from any normative wording and
thus it is inappropriate for a note. The rule for volatile objects was
moved for the same reason.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe