4.1.4 Attributes
Term entry: attribute —
characteristic or property of an entity that can be queried, and in some
cases specified
Syntax
range_attribute_designator ::= Range[(
static_expression)]
Name Resolution Rules
Discussion: The first part of this rule
is essentially a "preference" against implicit dereference,
so that it is possible to ask for, say, 'Size of an access object, without
automatically getting the size of the object designated by the access
object. This rule applies to 'Access, 'Unchecked_Access, 'Size, and 'Address,
and any other attributes that are defined for at least some access objects.
The second part of this rule implies that, for
a parameterless function F, F'Address is the address of F, whereas F'Size
is the size of the anonymous constant returned by F.
We normally talk in terms of expected type or
profile for name resolution rules, but we don't do this for attributes
because certain attributes are legal independent of the type or the profile
of the
prefix.
{
AI95-00114-01}
Other than the rules given above, the Name Resolution Rules for the
prefix
of each attribute are defined as Name Resolution Rules for that attribute.
If no such rules are defined, then no context at all should be used when
resolving the
prefix.
In particular, any knowledge about the kind of entities required must
not be used for resolution unless that is required by Name Resolution
Rules. This matters in obscure cases; for instance, given the following
declarations:
function Get_It return Integer is ... -- (1)
function Get_It return Some_Record_Type is ... -- (2)
if Get_It'Valid then
{
AI05-0005-1}
even though the Valid attribute is only defined for objects of scalar
types, and thus cannot be applied to the result of function (2). That
information cannot be used to resolve the
prefix.
The same would be true if (2) had been a procedure; even though the procedure
does not denote an object, the
attribute_reference
is still illegal.
Legality Rules
Static Semantics
{
AI05-0006-1}
{
AI12-0032-1}
{
AI12-0159-1}
An
attribute_reference
denotes a value, an object, a subprogram, or some other kind of program
entity. Unless explicitly specified otherwise, for an
attribute_reference
that denotes a value or an object, if its type is scalar, then its nominal
subtype is the base subtype of the type; if its type is tagged, its nominal
subtype is the first subtype of the type; otherwise, its nominal subtype
is a subtype of the type without any constraint,
null_exclusion,
or predicate.
Similarly, unless explicitly specified
otherwise, for an
attribute_reference
that denotes a function, when its result type is scalar, its result subtype
is the base subtype of the type, when its result type is tagged, the
result subtype is the first subtype of the type, and when the result
type is some other type, the result subtype is a subtype of the type
without any constraint,
null_exclusion,
or predicate.
Ramification: The attributes defined
by the language are summarized in
K.2. Implementations
can define additional attributes.
Discussion: {
AI05-0006-1}
The nominal subtype is primarily a concern when an
attribute_reference,
or a call on an
attribute_reference,
is used as the
expression
of a case statement, due to the full coverage requirement based on the
nominal subtype. For nondiscrete cases, we define the nominal subtype
mainly for completeness. Implementations may specify otherwise for implementation-defined
attribute functions.
The rule is written to match the meaning of
the italicized
T in the definition of attributes such as Input;
see
4.5.1.
To be honest: {
AI05-0006-1}
We don't worry about the fact that “base subtype” is not
explicitly defined for the universal types. Since it is not possible
to constrain a universal numeric type, all subtypes are unconstrained,
and hence can be considered base subtypes. The wording above could be
altered to bypass this issue, but it doesn't seem necessary, since universal
integer is handled specially in the rules for case expression full coverage,
and we don't allow user-defined functions for attribute functions whose
result type is universal.
[A
range_attribute_reference
X'Range(N) is equivalent to the
range
X'First(N) .. X'Last(N), except that the
prefix
is only evaluated once. Similarly, X'Range is equivalent to X'First ..
X'Last, except that the
prefix
is only evaluated once.]
Dynamic Semantics
Implementation Permissions
{
8652/0015}
{
AI95-00093-01}
{
AI12-0362-2}
An implementation may provide implementation-defined attributes; the
identifier
for such an implementation-defined attribute shall differ from those
of the language-defined attributes.
Implementation defined: Implementation-defined
attributes.
Ramification: They cannot be reserved
words because reserved words are not legal identifiers.
The semantics of implementation-defined attributes,
and any associated rules, are, of course, implementation defined. For
example, the implementation defines whether a given implementation-defined
attribute can be used in a static expression.
{
AI12-0362-2}
An implementation may extend the definition of a language-defined attribute
by accepting uses of that attribute that would otherwise be illegal in
the following cases:
in order to support compatibility with a previous
edition of of this Reference Manual; or
Ramification: {
8652/0015}
{
AI95-00093-01}
Implementations are allowed to support the Small attribute for floating
types, as this was defined in Ada 83, even though the name would conflict
with a language-defined attribute.
in the case of a language-defined attribute whose
prefix is
required by this document to be a floating point subtype, an implementation
may accept an
attribute_reference
whose
prefix
is a fixed point subtype[; the semantics of such an
attribute_reference
are implementation defined.]
NOTE 1 Attributes are defined throughout
this document, and are summarized in
K.2.
Proof: {
AI95-00235}
In the general case, there is no “expected type” for the
prefix of
an
attribute_reference.
In the special case of 'Access, there is an “expected type”
or “expected profile” for the
prefix.
Reason: 'Access is a special case, because
without it, it would be very difficult to take 'Access of an overloaded
subprogram.
Examples
Examples of attributes:
Color'First --
minimum value of the enumeration type Color (see 3.5.1)
Rainbow'Base'First --
same as Color'First (see 3.5.1)
Real'Digits --
precision of the type Real (see 3.5.7)
Board'Last(2) --
upper bound of the second dimension of Board (see 3.6.1)
Board'Range(1) --
index range of the first dimension of Board (see 3.6.1)
Pool(K)'Terminated --
True if task Pool(K) is terminated (see 9.1)
Date'Size --
number of bits for records of type Date (see 3.8)
Message'Address --
address of the record variable Message
--
(see 3.7.1)
Extensions to Ada 83
We now uniformly treat X'Range
as X'First..X'Last, allowing its use with scalar subtypes.
We allow any integer type in the
static_expression
of an attribute designator, not just a value of
universal_integer.
The preference rules ensure upward compatibility.
Wording Changes from Ada 83
We use the syntactic category
attribute_reference
rather than simply "attribute" to avoid confusing the name
of something with the thing itself.
The Ada 95 name resolution rules are a bit more
explicit than in Ada 83. The Ada 83 rule said that the "meaning
of the prefix of an attribute must be determinable independently of the
attribute designator and independently of the fact that it is the prefix
of an attribute". That isn't quite right since the meaning even
in Ada 83 embodies whether or not the prefix is interpreted as a parameterless
function call, and in Ada 95, it also embodies whether or not the prefix
is interpreted as an implicit_dereference. So the attribute designator
does make a difference — just not much.
Note however that if the attribute designator
is Access, it makes a big difference in the interpretation of the prefix
(see
3.10.2).
Wording Changes from Ada 95
{
8652/0015}
{
AI95-00093-01}
Corrigendum: The wording was changed to allow implementations
to continue to implement the Ada 83 Small attribute. This was always
intended to be allowed.
{
AI95-00235-01}
The note about resolving prefixes of attributes was updated to reflect
that the prefix of an Access attribute now has an expected type (see
3.10.2).
Wording Changes from Ada 2005
Wording Changes from Ada 2012
{
AI12-0159-1}
Corrigendum: Added wording so it is clear that predicates don't
apply to the result of an attribute.
{
AI12-0362-2}
Added a permission to support fixed point versions of float attributes,
such as the rounding attributes found in
A.5.3.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe