B.1 Interfacing AspectsInterfacing Pragmas
An interfacing aspect is a representation
aspect that is one of the aspects Import, Export, Link_Name, External_Name,
the A pragma
Import aspect to have the value True
used to import an entity defined in a foreign language into an Ada program,
thus allowing a foreign-language subprogram to be called from Ada, or
a foreign-language variable to be accessed from Ada. In contrast, specifying
the a pragma
Export aspect to have the value True
used to export an Ada entity to a foreign language, thus allowing an
Ada subprogram to be called from a foreign language, or an Ada object
to be accessed from a foreign language. The pragmas
Import and Export aspects
are intended primarily
for objects and subprograms, although implementations are allowed to
support other entities. The Link_Name and External_Name
aspects are used to specify the link name and external name, respectively,
to be used to identify imported or exported entities in the external
for Import: Entity
is imported from another language.
for Export: Entity
is exported to another language.
for External_Name: Name
used to identify an imported or exported entity.
for Link_Name: Linker
symbol used to identify an imported or exported entity.
The A pragma
is used to indicate specify
that an Ada entity should use the conventions of another language. It
is intended primarily for types and “callback” subprograms.
For example, “with pragma
Convention => (
” on the declaration of an
array type Matrix
implies that Matrix should be represented according
to the conventions of the supported Fortran implementation, namely column-major
for Convention: Calling
convention or other convention used for interfacing to other languages.
Linker_Options is used to specify the system linker parameters needed
when a given compilation unit is included in a partition.
The form of a
interfacing pragma is a representation pragma
that is one of the pragmas
Import, Export, or Convention. Their forms, together with that of the
Name Resolution Rules
The Import and Export aspects are of type Boolean.
The Link_Name and External_Name aspects are of expected
type for a string_expression
in an interfacing pragma or in pragma Linker_Options is
There is no language-defined
support for external or link names of type Wide_String, or of other string
types. Implementations may, of course, have additional aspects pragmas
for that purpose. Note that allowing both String and Wide_String in the
same aspect_definition pragma
would cause ambiguities.
The aspect Convention shall
be specified by a convention_identifier
which of an interfacing
shall be the name of a convention
. The convention
names are implementation defined, except for certain language-defined
ones, such as Ada and Intrinsic, as explained in 6.3.1
convention names generally represent the calling conventions of foreign
languages, language implementations, or specific run-time models.]
convention of a callable entity is its calling convention
Implementation defined: Implementation-defined
We considered representing
the convention names using an enumeration type declared in System. Then,
would be changed to convention_name
and we would make its expected type be the enumeration type. We didn't
do this because it seems to introduce extra complexity, and because the
list of available languages is better represented as the list of children
of package Interfaces — a more open-ended sort of list.
is a convention_identifier
for a language, then a type T is said to be compatible with convention
, (alternatively, is said to be an L-compatible type
any of the following conditions are met:
T is declared in a language interface package corresponding
and is defined to be L
-compatible (see B.3
has been specified for T in a pragma
, and T is eligible for convention L
; that is:
T is an array type with either an
unconstrained or statically-constrained first subtype, and its component
type is L-compatible,
T is a record type that has no discriminants
and that only has components with statically-constrained subtypes, and
each component type is L-compatible,
T is an access-to-object type, and
type is L
-compatible, and its designated
subtype is not an unconstrained array subtype,
T is an access-to-subprogram type,
and its designated profile's parameter and result types are all L-compatible.
T is derived from an L-compatible type,
The implementation permits T as an L-compatible
Discussion: For example, an implementation
might permit Integer as a C-compatible type, though the C type to which
it corresponds might be different in different environments.
If the pragma
Convention aspect is specified for applies
a type, then the type shall either be compatible with or eligible
for the specified
convention specified in the pragma
If a type is derived from an L
-compatible type, the derived type
is by default L
-compatible, but it is also permitted to specify
for the derived type.
It is permitted to specify the pragma
for an incomplete type,
but in the complete declaration each component must be L
If each component of a record type is L
-compatible, then the record
type itself is only L
-compatible if it has a
specified a pragma
For declarations of deferred constants and subprograms, we explicitly
mention that no completion is allowed when
True explicitly as a possible completion
For other declarations that require completions, we ignore the possibility
of the aspect pragma
Import being True
. Nevertheless, if an implementation
chooses to allow specifying aspect a
Import to be True for complete
the declaration of a task, protected type, incomplete type, private type,
etc., it may do so, and the normal completion is then not allowed for
An entity with
a True specified as the Entity argument
to a pragma
) is said to be imported
). An entity shall
not be both imported and exported.
The declaration of an imported object shall not include
an explicit initialization expression. [Default initializations are not
Proof: This follows from the “Notwithstanding
...” wording in the Dynamics Semantics paragraphs below.
The type of an imported or exported object shall be compatible with the
specified Convention aspect, if any convention
specified in the corresponding pragma
Ramification: This implies, for example,
that importing an Integer object might be illegal, whereas importing
an object of type Interfaces.C.int would be permitted.
For an imported or exported subprogram, the result and parameter types
shall each be compatible with the specified Convention
aspect, if any convention specified in the
(if any) used to directly specify an The
external name and link name string_expressions
of a pragma
Export, External_Name, or Link_Name aspect shall
be a static expression. The and the
of a pragma
shall be static. An External_Name or Link_Name aspect shall be specified only for an entity
that is either imported or exported.
28 and 29 were deleted.
Export, and Convention pragmas
are representation pragmas that specify the convention aspect
of representation. In
addition, Import and Export pragmas
specify the imported and exported aspects of representation,
interfacing pragma is a program unit pragma when applied to a program
unit (see 10.1.5).
An interfacing pragma defines the convention of
the entity denoted by the local_name.
The Convention aspect convention
represents the calling convention or representation convention of the
entity. For an access-to-subprogram type, it represents the calling convention
of designated subprograms. In addition:
A True pragma
Import aspect indicates specifies
that the entity is defined externally (that is, outside the Ada program). This aspect is never inherited; if not directly specified, the Import
aspect is False.
A True pragma
Export aspect indicates specifies
that the entity is used externally. This aspect
is never inherited; if not directly specified, the Export aspect is False.
For an entity with a True A
Import or Export aspect, an optionally
specifies an entity's
external name, link name, or both may also be specified
An external name
string value for the name used by a foreign language program either for
an entity that an Ada program imports, or for referring to an entity
that an Ada program exports.
A link name
is a string
value for the name of an exported or imported entity, based on the conventions
of the foreign language's compiler in interfacing with the system's linker
The meaning of link names is implementation defined.
If neither a link name nor the Address attribute of an imported or exported
entity is specified, then a link name is chosen in an implementation-defined
manner, based on the external name if one is specified.
Implementation defined: The meaning of
Ramification: For example, an implementation
might always prepend "_", and then pass it to the system linker.
Implementation defined: The manner of
choosing link names when neither the link name nor the address of an
imported or exported entity is specified.
Ramification: Normally, this will be
the entity's defining name, or some simple transformation thereof.
Pragma Linker_Options has the effect of passing its
string argument as a parameter to the system linker (if one exists),
if the immediately enclosing compilation unit is included in the partition
being linked. The interpretation of the string argument, and the way
in which the string arguments from multiple Linker_Options pragmas are
combined, is implementation defined.
Implementation defined: The effect of
what this International Standard says elsewhere, the elaboration of a
declaration with a True Import aspect denoted
by the local_name
of a pragma
does not create the entity. Such an elaboration has no
other effect than to allow the defining name to denote the external entity.
Ramification: This implies that default
initializations are skipped. (Explicit initializations are illegal.)
For example, an imported access object is not initialized to null.
Note that the local_name
in a pragma
Import might denote more than one declaration; in that case, the entity
of all of those declarations will be the external entity.
This “notwithstanding” wording is better than saying “unless
aspect named by a
Import is True
” on every definition
of elaboration. It says we recognize the contradiction, and this rule
It is the programmer's responsibility
to ensure that the use of interfacing aspects pragmas does not violate Ada semantics; otherwise, program execution is erroneous.
If an implementation supports pragma
language, then it should also allow the main subprogram to be written
in that language. It should support some mechanism for invoking the elaboration
of the Ada library units included in the system, and for invoking the
finalization of the environment task. On typical systems, the recommended
mechanism is to provide two subprograms whose link names are "adainit"
and "adafinal". Adainit should contain the elaboration code
for library units. Adafinal should contain the finalization code. These
subprograms should have no effect the second and subsequent time they
Implementation Advice: If
Export is supported for a language,
the main program should be able to be written in that language. Subprograms
named "adainit" and "adafinal" should be provided
for elaboration and finalization of the environment task.
Ramification: For example, if the main
subprogram is written in C, it can call adainit before the first call
to an Ada subprogram, and adafinal after the last.
Automatic elaboration of preelaborated packages should be provided when
specifying the pragma
Export aspect as True
Implementation Advice: Automatic
elaboration of preelaborated packages should be provided when specifying
the pragma Export aspect as True is
For each supported convention L
other than Intrinsic, an implementation
should support specifying the
Export aspects pragmas
for objects of L
-compatible types and for subprograms, and the pragma
types and for subprograms, presuming the other language has corresponding
features. Specifying the Pragma
need not be supported
for scalar types.
Implementation Advice: For
each supported convention L other than Intrinsic, specifying
the aspects pragmas Import and Export should be supported for objects of L-compatible
types and for subprograms, and aspect pragma Convention should be supported for L-eligible types and for subprograms.
Specifying aspect Pragma
Convention is not necessary for scalar types, since the language interface
packages declare scalar types corresponding to those provided by the
respective foreign languages.
If an implementation supports interfacing to the
C++ entities not supported by B.3
it should do so via the convention identifier C_Plus_Plus (in additional
to any C++-implementation-specific ones).
The reason for giving the advice about C++ is to encourage uniformity
among implementations, given that the name of the language is not syntactically
legal as an identifier
. We place this advice in the AARM, rather than the RM95 proper, because
(as of this writing) C++ is not an international standard, and we don't
want to refer to a such a language from an international standard.
Implementations may place restrictions on interfacing aspects pragmas
for example, requiring each exported entity to be declared at the library
Arbitrary restrictions are allowed
Ramification: Such a restriction might
be to disallow them altogether. Alternatively, the implementation might
allow them only for certain kinds of entities, or only for certain conventions.
The Convention aspect in combination with the A
Import aspect indicates specifies
the conventions for accessing external entities. It is possible that
the actual entity is written in assembly language, but reflects the conventions
of a particular language. For example, with
Convention => Ada pragma
can be used to interface to an assembly language
routine that obeys the Ada compiler's calling conventions.
To obtain “call-back” to an Ada subprogram from a foreign
language environment, the pragma
should be specified both
for the access-to-subprogram type and the specific subprogram(s) to which
'Access is applied.
45 and 46 were deleted.
It is illegal to specify more than one of Import,
Export, or Convention for a given entity.
in an interfacing pragma can denote more than one entity in the case
of overloading. Such a pragma
applies to all of the denoted entities.
The Intrinsic convention (see 6.3.1
that the entity is somehow “built in” to the implementation.
Thus, it generally does not make sense for users to specify Intrinsic
along with specifying that the entity is imported in
a pragma Import
The intention is that only implementations will specify Intrinsic for
an imported entity in a pragma
. The language also defines certain subprograms to be Intrinsic.
There are many imaginable interfacing aspects pragmas
that don't make any sense. For example, setting the Convention of a protected
procedure to Ada is probably wrong. Rather than enumerating all such
cases, however, we leave it up to implementations to decide what is sensible.
If both External_Name and Link_Name are specified for a
given entity an Import or Export pragma
then the External_Name is ignored.
This paragraph was
An interfacing pragma might result in an effect
that violates Ada semantics.
Example of interfacing
Sqrt (X : Float) return
with Import => True, Convention => Fortran
type Matrix is array (Natural range <>, Natural range <>) of Float
with Convention => Fortran;
function Invert (M : Matrix Exp (X : Float
) return Matrix
with Import => True, Convention => Fortran Float
pragma Import(Fortran, Sqrt);
pragma Import(Fortran, Exp);
Extensions to Ada 83
Interfacing pragmas are
new to Ada 95. Pragma Import replaces Ada 83's pragma Interface. Existing
implementations can continue to support pragma Interface for upward compatibility.
Wording Changes from Ada 95
Corrigendum: Clarified that pragmas
Import and Export work like a subprogram call; parameters cannot be omitted
unless named notation is used. (Reordering is still not permitted, however.)
Added wording to say all bets are off if foreign
code doesn't follow the semantics promised by the Ada specifications.
Incompatibilities With Ada 2005
Correction: Access types
that designate unconstrained arrays are no longer defined to be L-compatible.
Such access-to-arrays require bounds information, which is likely to
be incompatible with a foreign language. The change will allow (but not
require) compilers to reject bad uses, which probably will not work anyway.
Note that implementations can still support any type that it wants as
L-compatible; such uses will not be portable, however. As such,
there should be little existing code that will be impacted (compilers
probably already rejected cases that could not be translated, whether
or not the language allowed doing so formally).
Extensions to Ada 2005
Aspects Convention, Import,
Export, Link_Name, and External_Name are new; pragmas
Convention, Import, and Export are now obsolescent.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe