4.5.2 Relational Operators and Membership Tests
= (equals) and /= (not equals) are predefined
for nonlimited types.
are the ordering operators
< (less than), <= (less than
or equal), > (greater than), and >= (greater than or equal).
ordering operators are predefined for scalar types, and for discrete
, that is, one-dimensional array types whose components
are of a discrete type.
, using in
or not in
whether or not a value belongs to any given subtype or range, is equal
to any given value, has a tag that identifies a type that is covered
by a given type, or is convertible to and has an accessibility level
appropriate for a given access type. Membership tests are allowed for
Name Resolution Rules
For a membership test, if the tested_simple_expression
is of a tagged class-wide type, then the tested type shall be (visibly)
If a membership test includes one or more choice_simple_expression
and the tested type of the membership test is limited, then the tested
type of the membership test shall have a visible primitive equality operator;
if the tested type of the membership test is nonlimited with a user-defined
primitive equality operator that is defined at a point where the type
is limited, the tested type shall be a record type or record extension.
The result type of a membership test is the predefined
The equality operators
are predefined for every specific type T that is not limited,
and not an anonymous access type, with the following specifications:
function "=" (Left, Right : T) return Boolean
function "/="(Left, Right : T) return Boolean
The following additional
equality operators for the universal_access type are declared
in package Standard for use with anonymous access types:
function "=" (Left, Right : universal_access) return Boolean
function "/="(Left, Right : universal_access) return Boolean
The ordering operators
are predefined for every specific scalar type T, and for every
discrete array type T, with the following specifications:
function "<" (Left, Right : T) return Boolean
function "<="(Left, Right : T) return Boolean
function ">" (Left, Right : T) return Boolean
function ">="(Left, Right : T) return Boolean
Name Resolution Rules
At least one of the
operands of an equality operator for universal_access
of a specific anonymous access type. Unless the predefined equality operator
is identified using an expanded name with prefix
denoting the package Standard, neither operand shall be of an access-to-object
type whose designated type is D
'Class, where D
has a user-defined primitive equality operator such that:
its result type is Boolean;
it is declared immediately within the same declaration
list as D or any partial or incomplete view of D; and
at least one of its operands is an access parameter
with designated type D.
At least one of the operands of the equality operators
for universal_access shall be of type universal_access,
or both shall be of access-to-object types, or both shall be of access-to-subprogram
When both are of access-to-object types, the designated
types shall be the same or one shall cover the other, and if the designated
types are elementary or array types, then the designated subtypes shall
When both are of access-to-subprogram types, the
designated profiles shall be subtype conformant.
If the profile of an explicitly declared primitive
equality operator of an untagged record type is type conformant with
that of the corresponding predefined equality operator, the declaration
shall occur before the type is frozen. In addition, no type shall have
been derived from the untagged record type before the declaration of
the primitive equality operator.
In addition to the
places where Legality Rules normally apply (see 12.3
this rule applies also in the private part of an instance of a generic
For discrete types, the predefined relational operators
are defined in terms of corresponding mathematical operations on the
position numbers of the values of the operands.
For real types, the predefined relational operators
are defined in terms of the corresponding mathematical operations on
the values of the operands, subject to the accuracy of the type.
Two access-to-object values are equal if they designate
the same object, or if both are equal to the null value of the access
Two access-to-subprogram values are equal if they
are the result of the same evaluation of an Access attribute_reference
or if both are equal to the null value of the access type. Two access-to-subprogram
values are unequal if they designate different subprograms.
is unspecified whether two access values that designate the same subprogram
but are the result of distinct evaluations of Access attribute_reference
are equal or unequal.
For a type extension, predefined
equality is defined in terms of the primitive (possibly user-defined)
equals operator for the parent type and for any components that have
a record type in the extension part, and predefined equality for any
other components not inherited from the parent type.
For a private type, if its full type is a record
type or a record extension, predefined equality is defined in terms of
the primitive equals operator of the full type; otherwise, predefined
equality for the private type is that of its full type.
other composite types, the predefined equality operators (and certain
other predefined operations on composite types — see 4.5.1
) are defined in terms of the corresponding
operation on matching components
, defined as follows:
For two one-dimensional arrays of the same type,
matching components are those (if any) whose index values match in the
following sense: the lower bounds of the index ranges are defined to
match, and the successors of matching indices are defined to match;
For two multidimensional arrays of the same type,
matching components are those whose index values match in successive
The analogous definitions apply if the types of the
two objects or values are convertible, rather than being the same.
Given the above definition
of matching components, the result of the predefined equals operator
for composite types (other than for those composite types covered earlier)
is defined as follows:
If there are no components, the result is defined
to be True;
If there are unmatched components, the result is
defined to be False;
Otherwise, the result is defined in terms of the
primitive equals operator for any matching components that are records,
and the predefined equals for any other matching components.
If the primitive equals operator for an untagged
record type is abstract, then Program_Error is raised at the point of
any call to that abstract subprogram, implicitly as part of an equality
operation on an enclosing composite object, or in an instance of a generic
with a formal private type where the actual type is a record type with
an abstract "=".
For any composite type, the order in which "="
is called for components is unspecified. Furthermore, if the result can
be determined before calling "=" on some components, it is
unspecified whether "=" is called on those components.
The predefined "/=" operator gives the
complementary result to the predefined "=" operator.
For a discrete array type, the
predefined ordering operators correspond to lexicographic order
using the predefined order relation of the component type: A null array
is lexicographically less than any array having at least one component.
In the case of nonnull arrays, the left operand is lexicographically
less than the right operand if the first component of the left operand
is less than that of the right; otherwise, the left operand is lexicographically
less than the right operand only if their first components are equal
and the tail of the left operand is lexicographically less than that
of the right (the tail
consists of the remaining components beyond
the first and can be null).
For the evaluation of a membership test using in
has more than one membership_choice
of the membership test is evaluated first and the result of the operation
is equivalent to that of a sequence consisting of an individual membership
test on each membership_choice
combined with the short-circuit control form or else
An individual membership
test yields the result True if:
is a choice_simple_expression
and the tested_simple_expression
is equal to the value of the membership_choice
If the tested type is a record type or a record extension, or is limited
at the point where the membership test occurs, the test uses the primitive
equality for the type; otherwise, the test uses predefined equality.
if the type of the tested_simple_expression
is class-wide, the value has a tag that identifies a type covered by
the tested type;
if the tested type is an access
type and the named subtype excludes null, the value of the tested_simple_expression
is not null;
if the tested type is a general
access-to-object type, the type of the tested_simple_expression
is convertible to the tested type and its accessibility level is no deeper
than that of the tested type; further, if the designated type of the
tested type is tagged and the tested_simple_expression
is nonnull, the tag of the object designated by the value of the tested_simple_expression
is covered by the designated type of the tested type.
Otherwise, the test yields the result False.
A membership test using not in gives the complementary
result to the corresponding membership test using in.
For all nonlimited types declared in language-defined
packages, the "=" and "/=" operators of the type
shall behave as if they were the predefined equality operators for the
purposes of the equality of composite types and generic formal types.
This paragraph was
NOTE If a composite type has components
that depend on discriminants, two values of this type have matching components
if and only if their discriminants are equal. Two nonnull arrays have
matching components if and only if the length of each dimension is the
same for both.
Examples of expressions
involving relational operators and membership tests:
X /= Y
A_String = "A" -- True (see 3.3.1)
"" < A_String and
A_String < "Aa" -- True
A_String < "Bb" and
A_String < "A " -- True
My_Car = null
-- True if My_Car has been set to null (see 3.10.1)
My_Car = Your_Car -- True if we both share the same car
-- True if the two cars are identical
N not in
1 .. 10 -- range membership test
Mon .. Fri -- range membership test
Weekday -- subtype membership test (see 3.5.1)
Clubs | Spades -- list membership test (see 3.5.1)
Disk_Unit -- subtype membership test (see 3.8.1)
Addition'Class -- class membership test (see 3.9.1)
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe