Commit cb2d884d by Arnaud Charlet

gnat_rm.texi, [...]: Now automatically generated from sphinx in the doc directory.

2015-02-20  Arnaud Charlet  <charlet@adacore.com>                      

        * gnat_rm.texi, gnat_ugn.texi: Now automatically generated from
        sphinx in the doc directory.
        * doc: New directory containing sphinx versions of gnat_rm and gnat_ugn

From-SVN: r220837
parent 07a64c02
# Makefile for Sphinx documentation
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = DOC_NAME=$* sphinx-build
PAPER =
BUILDDIR = build
SOURCEDIR = .
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) \
-c $(SOURCEDIR)/share \
-d $(BUILDDIR)/$*/doctrees \
$(SOURCEDIR)
DOC_LIST=gnat_rm gnat_ugn
FMT_LIST=html pdf txt info
.PHONY: help clean
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " DOC_NAME.html to make standalone HTML files"
@echo " DOC_NAME.pdf to make LaTeX files and run them through pdflatex"
@echo " DOC_NAME.txt to make text files"
@echo " DOC_NAME.texinfo to make Texinfo files"
@echo " DOC_NAME.info to make info files"
@echo " DOC_NAME.all to build DOC_NAME for all previous formats"
@echo " all to build all documentations in all formats"
@echo " html-all same as previous rule but only for HTML format"
@echo " pdf-all same as previous rule but only for PDF format"
@echo " txt-all same as previous rule but only for text format"
@echo " texinfo-all same as previous rule but only for texinfo format"
@echo " info-all same as previous rule but only for info format"
@echo ""
@echo "DOC_NAME should be a documentation name in the following list:"
@echo " $(DOC_LIST)"
@echo ""
@echo "source and location can be overriden using SOURCEDIR and BUILDDIR variables"
clean:
-rm -rf $(BUILDDIR)/*/html \
$(BUILDDIR)/*/pdf \
$(BUILDDIR)/*/txt \
$(BUILDDIR)/*/info
%.html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/$*/html
%.pdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/$*/pdf
cp $(SOURCEDIR)/share/sphinx.sty $(BUILDDIR)/$*/pdf
$(MAKE) -C $(BUILDDIR)/$*/pdf all-pdf LATEXOPTS="-interaction=nonstopmode"
%.txt:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/$*/txt
$(MAKE) -C $(BUILDDIR)/$*/txt plaintext
%.info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/$*/info
$(MAKE) -C $(BUILDDIR)/$*/info info
%.texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/$*/texinfo
html-all: $(foreach doc, $(DOC_LIST), $(doc).html)
pdf-all: $(foreach doc, $(DOC_LIST), $(doc).pdf)
txt-all: $(foreach doc, $(DOC_LIST), $(doc).txt)
texinfo-all: $(foreach doc, $(DOC_LIST), $(doc).texinfo)
%.all:
$(MAKE) $(foreach fmt, $(FMT_LIST), $*.$(fmt))
all: $(foreach fmt, $(FMT_LIST), $(fmt).all)
GNAT Reference Manual
=====================
*GNAT, The GNU Ada Development Environment*
.. only:: PRO
*GNAT Pro Edition*
| Version |version|
| Date: |today|
.. only:: GPL
*GNAT GPL Edition*
| Version |version|
| Date: |today|
.. only:: FSF
.. raw:: texinfo
@include gcc-common.texi
GCC version @value{version-GCC}@*
AdaCore
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover Texts being "GNAT Reference
Manual", and with no Back-Cover Texts. A copy of the license is
included in the section entitled :ref:`gnu_fdl`.
.. toctree::
:numbered:
:maxdepth: 3
gnat_rm/about_this_guide
gnat_rm/implementation_defined_pragmas
gnat_rm/implementation_defined_aspects
gnat_rm/implementation_defined_attributes
gnat_rm/standard_and_implementation_defined_restrictions
gnat_rm/implementation_advice
gnat_rm/implementation_defined_characteristics
gnat_rm/intrinsic_subprograms
gnat_rm/representation_clauses_and_pragmas
gnat_rm/standard_library_routines
gnat_rm/the_implementation_of_standard_i_o
gnat_rm/the_gnat_library
gnat_rm/interfacing_to_other_languages
gnat_rm/specialized_needs_annexes
gnat_rm/implementation_of_specific_ada_features
gnat_rm/implementation_of_ada_2012_features
gnat_rm/obsolescent_features
gnat_rm/compatibility_and_porting_guide
.. raw:: latex
\appendix
.. toctree::
:maxdepth: 3
share/gnu_free_documentation_license
.. _About_This_Guide:
****************
About This Guide
****************
.. only:: PRO
For ease of exposition, 'GNAT Pro' will be referred to simply as
'GNAT' in the remainder of this document.
This manual contains useful information in writing programs using the
GNAT compiler. It includes information on implementation dependent
characteristics of GNAT, including all the information required by
Annex M of the Ada language standard.
GNAT implements Ada 95, Ada 2005 and Ada 2012, and it may also be
invoked in Ada 83 compatibility mode.
By default, GNAT assumes Ada 2012,
but you can override with a compiler switch
to explicitly specify the language version.
(Please refer to the *GNAT User's Guide* for details on these switches.)
Throughout this manual, references to 'Ada' without a year suffix
apply to all the Ada versions of the language.
Ada is designed to be highly portable.
In general, a program will have the same effect even when compiled by
different compilers on different platforms.
However, since Ada is designed to be used in a
wide variety of applications, it also contains a number of system
dependent features to be used in interfacing to the external world.
.. index:: Implementation-dependent features
.. index:: Portability
Note: Any program that makes use of implementation-dependent features
may be non-portable. You should follow good programming practice and
isolate and clearly document any sections of your program that make use
of these features in a non-portable manner.
What This Reference Manual Contains
===================================
This reference manual contains the following chapters:
* :ref:`Implementation_Defined_Pragmas`, lists GNAT implementation-dependent
pragmas, which can be used to extend and enhance the functionality of the
compiler.
* :ref:`Implementation_Defined_Attributes`, lists GNAT
implementation-dependent attributes, which can be used to extend and
enhance the functionality of the compiler.
* :ref:`Standard_and_Implementation_Defined_Restrictions`, lists GNAT
implementation-dependent restrictions, which can be used to extend and
enhance the functionality of the compiler.
* :ref:`Implementation_Advice`, provides information on generally
desirable behavior which are not requirements that all compilers must
follow since it cannot be provided on all systems, or which may be
undesirable on some systems.
* :ref:`Implementation_Defined_Characteristics`, provides a guide to
minimizing implementation dependent features.
* :ref:`Intrinsic_Subprograms`, describes the intrinsic subprograms
implemented by GNAT, and how they can be imported into user
application programs.
* :ref:`Representation_Clauses_and_Pragmas`, describes in detail the
way that GNAT represents data, and in particular the exact set
of representation clauses and pragmas that is accepted.
* :ref:`Standard_Library_Routines`, provides a listing of packages and a
brief description of the functionality that is provided by Ada's
extensive set of standard library routines as implemented by GNAT.
* :ref:`The_Implementation_of_Standard_I/O`, details how the GNAT
implementation of the input-output facilities.
* :ref:`The_GNAT_Library`, is a catalog of packages that complement
the Ada predefined library.
* :ref:`Interfacing_to_Other_Languages`, describes how programs
written in Ada using GNAT can be interfaced to other programming
languages.
* :ref:`Specialized_Needs_Annexes`, describes the GNAT implementation of all
of the specialized needs annexes.
* :ref:`Implementation_of_Specific_Ada_Features`, discusses issues related
to GNAT's implementation of machine code insertions, tasking, and several
other features.
* :ref:`Implementation_of_Ada_2012_Features`, describes the status of the
GNAT implementation of the Ada 2012 language standard.
* :ref:`Obsolescent_Features` documents implementation dependent features,
including pragmas and attributes, which are considered obsolescent, since
there are other preferred ways of achieving the same results. These
obsolescent forms are retained for backwards compatibility.
* :ref:`Compatibility_and_Porting_Guide` presents some guidelines for
developing portable Ada code, describes the compatibility issues that
may arise between GNAT and other Ada compilation systems (including those
for Ada 83), and shows how GNAT can expedite porting applications
developed in other Ada environments.
* :ref:`gnu_fdl` contains the license for this document.
.. index:: Ada 95 Language Reference Manual
.. index:: Ada 2005 Language Reference Manual
This reference manual assumes a basic familiarity with the Ada 95 language, as
described in the
:title:`International Standard ANSI/ISO/IEC-8652:1995`.
It does not require knowledge of the new features introduced by Ada 2005,
(officially known as `ISO/IEC 8652:1995 with Technical Corrigendum 1
and Amendment 1`).
Both reference manuals are included in the GNAT documentation
package.
Conventions
===========
.. index:: Conventions, typographical
.. index:: Typographical conventions
Following are examples of the typographical and graphic conventions used
in this guide:
* `Functions`, `utility program names`, `standard names`,
and `classes`.
* `Option flags`
* :file:`File names`
* `Variables`
* *Emphasis*
* [optional information or parameters]
* Examples are described by text
::
and then shown this way.
* Commands that are entered by the user are shown as preceded by a prompt string
comprising the ``$`` character followed by a space.
Related Information
===================
See the following documents for further information on GNAT:
* :title:`GNAT User's Guide for Native Platforms`,
which provides information on how to use the
GNAT development environment.
* :title:`Ada 95 Reference Manual`, the Ada 95 programming language standard.
* :title:`Ada 95 Annotated Reference Manual`, which is an annotated version
of the Ada 95 standard. The annotations describe
detailed aspects of the design decision, and in particular contain useful
sections on Ada 83 compatibility.
* :title:`Ada 2005 Reference Manual`, the Ada 2005 programming language standard.
* :title:`Ada 2005 Annotated Reference Manual`, which is an annotated version
of the Ada 2005 standard. The annotations describe
detailed aspects of the design decision.
* :title:`Ada 2012 Reference Manual`, the Ada 2012 programming language standard.
* :title:`DEC Ada, Technical Overview and Comparison on DIGITAL Platforms`,
which contains specific information on compatibility between GNAT and
DEC Ada 83 systems.
* :title:`DEC Ada, Language Reference Manual`, part number AA-PYZAB-TK, which
describes in detail the pragmas and attributes provided by the DEC Ada 83
compiler system.
.. _Compatibility_and_Porting_Guide:
*******************************
Compatibility and Porting Guide
*******************************
This chapter presents some guidelines for developing portable Ada code,
describes the compatibility issues that may arise between
GNAT and other Ada compilation systems (including those for Ada 83),
and shows how GNAT can expedite porting
applications developed in other Ada environments.
.. _Writing_Portable_Fixed-Point_Declarations:
Writing Portable Fixed-Point Declarations
=========================================
The Ada Reference Manual gives an implementation freedom to choose bounds
that are narrower by `Small` from the given bounds.
For example, if we write
.. code-block:: ada
type F1 is delta 1.0 range -128.0 .. +128.0;
then the implementation is allowed to choose -128.0 .. +127.0 if it
likes, but is not required to do so.
This leads to possible portability problems, so let's have a closer
look at this, and figure out how to avoid these problems.
First, why does this freedom exist, and why would an implementation
take advantage of it? To answer this, take a closer look at the type
declaration for `F1` above. If the compiler uses the given bounds,
it would need 9 bits to hold the largest positive value (and typically
that means 16 bits on all machines). But if the implementation chooses
the +127.0 bound then it can fit values of the type in 8 bits.
Why not make the user write +127.0 if that's what is wanted?
The rationale is that if you are thinking of fixed point
as a kind of 'poor man's floating-point', then you don't want
to be thinking about the scaled integers that are used in its
representation. Let's take another example:
.. code-block:: ada
type F2 is delta 2.0**(-15) range -1.0 .. +1.0;
Looking at this declaration, it seems casually as though
it should fit in 16 bits, but again that extra positive value
+1.0 has the scaled integer equivalent of 2**15 which is one too
big for signed 16 bits. The implementation can treat this as:
.. code-block:: ada
type F2 is delta 2.0**(-15) range -1.0 .. +1.0-(2.0**(-15));
and the Ada language design team felt that this was too annoying
to require. We don't need to debate this decision at this point,
since it is well established (the rule about narrowing the ranges
dates to Ada 83).
But the important point is that an implementation is not required
to do this narrowing, so we have a potential portability problem.
We could imagine three types of implementation:
(a) those that narrow the range automatically if they can figure
out that the narrower range will allow storage in a smaller machine unit,
(b) those that will narrow only if forced to by a `'Size` clause, and
(c) those that will never narrow.
Now if we are language theoreticians, we can imagine a fourth
approach: to narrow all the time, e.g. to treat
.. code-block:: ada
type F3 is delta 1.0 range -10.0 .. +23.0;
as though it had been written:
.. code-block:: ada
type F3 is delta 1.0 range -9.0 .. +22.0;
But although technically allowed, such a behavior would be hostile and silly,
and no real compiler would do this. All real compilers will fall into one of
the categories (a), (b) or (c) above.
So, how do you get the compiler to do what you want? The answer is give the
actual bounds you want, and then use a `'Small` clause and a
`'Size` clause to absolutely pin down what the compiler does.
E.g., for `F2` above, we will write:
.. code-block:: ada
My_Small : constant := 2.0**(-15);
My_First : constant := -1.0;
My_Last : constant := +1.0 - My_Small;
type F2 is delta My_Small range My_First .. My_Last;
and then add
.. code-block:: ada
for F2'Small use my_Small;
for F2'Size use 16;
In practice all compilers will do the same thing here and will give you
what you want, so the above declarations are fully portable. If you really
want to play language lawyer and guard against ludicrous behavior by the
compiler you could add
.. code-block:: ada
Test1 : constant := 1 / Boolean'Pos (F2'First = My_First);
Test2 : constant := 1 / Boolean'Pos (F2'Last = My_Last);
One or other or both are allowed to be illegal if the compiler is
behaving in a silly manner, but at least the silly compiler will not
get away with silently messing with your (very clear) intentions.
If you follow this scheme you will be guaranteed that your fixed-point
types will be portable.
.. _Compatibility_with_Ada_83:
Compatibility with Ada 83
=========================
.. index:: Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012)
Ada 95 and the subsequent revisions Ada 2005 and Ada 2012
are highly upwards compatible with Ada 83. In
particular, the design intention was that the difficulties associated
with moving from Ada 83 to later versions of the standard should be no greater
than those that occur when moving from one Ada 83 system to another.
However, there are a number of points at which there are minor
incompatibilities. The :title:`Ada 95 Annotated Reference Manual` contains
full details of these issues as they relate to Ada 95,
and should be consulted for a complete treatment.
In practice the
following subsections treat the most likely issues to be encountered.
.. _Legal_Ada_83_programs_that_are_illegal_in_Ada_95:
Legal Ada 83 programs that are illegal in Ada 95
------------------------------------------------
Some legal Ada 83 programs are illegal (i.e., they will fail to compile) in
Ada 95 and later versions of the standard:
* *Character literals*
Some uses of character literals are ambiguous. Since Ada 95 has introduced
`Wide_Character` as a new predefined character type, some uses of
character literals that were legal in Ada 83 are illegal in Ada 95.
For example:
.. code-block:: ada
for Char in 'A' .. 'Z' loop ... end loop;
The problem is that 'A' and 'Z' could be from either
`Character` or `Wide_Character`. The simplest correction
is to make the type explicit; e.g.:
.. code-block:: ada
for Char in Character range 'A' .. 'Z' loop ... end loop;
* *New reserved words*
The identifiers `abstract`, `aliased`, `protected`,
`requeue`, `tagged`, and `until` are reserved in Ada 95.
Existing Ada 83 code using any of these identifiers must be edited to
use some alternative name.
* *Freezing rules*
The rules in Ada 95 are slightly different with regard to the point at
which entities are frozen, and representation pragmas and clauses are
not permitted past the freeze point. This shows up most typically in
the form of an error message complaining that a representation item
appears too late, and the appropriate corrective action is to move
the item nearer to the declaration of the entity to which it refers.
A particular case is that representation pragmas
cannot be applied to a subprogram body. If necessary, a separate subprogram
declaration must be introduced to which the pragma can be applied.
* *Optional bodies for library packages*
In Ada 83, a package that did not require a package body was nevertheless
allowed to have one. This lead to certain surprises in compiling large
systems (situations in which the body could be unexpectedly ignored by the
binder). In Ada 95, if a package does not require a body then it is not
permitted to have a body. To fix this problem, simply remove a redundant
body if it is empty, or, if it is non-empty, introduce a dummy declaration
into the spec that makes the body required. One approach is to add a private
part to the package declaration (if necessary), and define a parameterless
procedure called `Requires_Body`, which must then be given a dummy
procedure body in the package body, which then becomes required.
Another approach (assuming that this does not introduce elaboration
circularities) is to add an `Elaborate_Body` pragma to the package spec,
since one effect of this pragma is to require the presence of a package body.
* *Numeric_Error is the same exception as Constraint_Error*
In Ada 95, the exception `Numeric_Error` is a renaming of `Constraint_Error`.
This means that it is illegal to have separate exception handlers for
the two exceptions. The fix is simply to remove the handler for the
`Numeric_Error` case (since even in Ada 83, a compiler was free to raise
`Constraint_Error` in place of `Numeric_Error` in all cases).
* *Indefinite subtypes in generics*
In Ada 83, it was permissible to pass an indefinite type (e.g, `String`)
as the actual for a generic formal private type, but then the instantiation
would be illegal if there were any instances of declarations of variables
of this type in the generic body. In Ada 95, to avoid this clear violation
of the methodological principle known as the 'contract model',
the generic declaration explicitly indicates whether
or not such instantiations are permitted. If a generic formal parameter
has explicit unknown discriminants, indicated by using `(<>)` after the
subtype name, then it can be instantiated with indefinite types, but no
stand-alone variables can be declared of this type. Any attempt to declare
such a variable will result in an illegality at the time the generic is
declared. If the `(<>)` notation is not used, then it is illegal
to instantiate the generic with an indefinite type.
This is the potential incompatibility issue when porting Ada 83 code to Ada 95.
It will show up as a compile time error, and
the fix is usually simply to add the `(<>)` to the generic declaration.
.. _More_deterministic_semantics:
More deterministic semantics
----------------------------
* *Conversions*
Conversions from real types to integer types round away from 0. In Ada 83
the conversion Integer(2.5) could deliver either 2 or 3 as its value. This
implementation freedom was intended to support unbiased rounding in
statistical applications, but in practice it interfered with portability.
In Ada 95 the conversion semantics are unambiguous, and rounding away from 0
is required. Numeric code may be affected by this change in semantics.
Note, though, that this issue is no worse than already existed in Ada 83
when porting code from one vendor to another.
* *Tasking*
The Real-Time Annex introduces a set of policies that define the behavior of
features that were implementation dependent in Ada 83, such as the order in
which open select branches are executed.
.. _Changed_semantics:
Changed semantics
-----------------
The worst kind of incompatibility is one where a program that is legal in
Ada 83 is also legal in Ada 95 but can have an effect in Ada 95 that was not
possible in Ada 83. Fortunately this is extremely rare, but the one
situation that you should be alert to is the change in the predefined type
`Character` from 7-bit ASCII to 8-bit Latin-1.
.. index:: Latin-1
* *Range of type `Character`*
The range of `Standard.Character` is now the full 256 characters
of Latin-1, whereas in most Ada 83 implementations it was restricted
to 128 characters. Although some of the effects of
this change will be manifest in compile-time rejection of legal
Ada 83 programs it is possible for a working Ada 83 program to have
a different effect in Ada 95, one that was not permitted in Ada 83.
As an example, the expression
`Character'Pos(Character'Last)` returned `127` in Ada 83 and now
delivers `255` as its value.
In general, you should look at the logic of any
character-processing Ada 83 program and see whether it needs to be adapted
to work correctly with Latin-1. Note that the predefined Ada 95 API has a
character handling package that may be relevant if code needs to be adapted
to account for the additional Latin-1 elements.
The desirable fix is to
modify the program to accommodate the full character set, but in some cases
it may be convenient to define a subtype or derived type of Character that
covers only the restricted range.
.. _Other_language_compatibility_issues:
Other language compatibility issues
-----------------------------------
* *-gnat83* switch
All implementations of GNAT provide a switch that causes GNAT to operate
in Ada 83 mode. In this mode, some but not all compatibility problems
of the type described above are handled automatically. For example, the
new reserved words introduced in Ada 95 and Ada 2005 are treated simply
as identifiers as in Ada 83. However,
in practice, it is usually advisable to make the necessary modifications
to the program to remove the need for using this switch.
See the `Compiling Different Versions of Ada` section in
the :title:`GNAT User's Guide`.
* Support for removed Ada 83 pragmas and attributes
A number of pragmas and attributes from Ada 83 were removed from Ada 95,
generally because they were replaced by other mechanisms. Ada 95 and Ada 2005
compilers are allowed, but not required, to implement these missing
elements. In contrast with some other compilers, GNAT implements all
such pragmas and attributes, eliminating this compatibility concern. These
include `pragma Interface` and the floating point type attributes
(`Emax`, `Mantissa`, etc.), among other items.
.. _Compatibility_between_Ada_95_and_Ada_2005:
Compatibility between Ada 95 and Ada 2005
=========================================
.. index:: Compatibility between Ada 95 and Ada 2005
Although Ada 2005 was designed to be upwards compatible with Ada 95, there are
a number of incompatibilities. Several are enumerated below;
for a complete description please see the
:title:`Annotated Ada 2005 Reference Manual`, or section 9.1.1 in
:title:`Rationale for Ada 2005`.
* *New reserved words.*
The words `interface`, `overriding` and `synchronized` are
reserved in Ada 2005.
A pre-Ada 2005 program that uses any of these as an identifier will be
illegal.
* *New declarations in predefined packages.*
A number of packages in the predefined environment contain new declarations:
`Ada.Exceptions`, `Ada.Real_Time`, `Ada.Strings`,
`Ada.Strings.Fixed`, `Ada.Strings.Bounded`,
`Ada.Strings.Unbounded`, `Ada.Strings.Wide_Fixed`,
`Ada.Strings.Wide_Bounded`, `Ada.Strings.Wide_Unbounded`,
`Ada.Tags`, `Ada.Text_IO`, and `Interfaces.C`.
If an Ada 95 program does a `with` and `use` of any of these
packages, the new declarations may cause name clashes.
* *Access parameters.*
A nondispatching subprogram with an access parameter cannot be renamed
as a dispatching operation. This was permitted in Ada 95.
* *Access types, discriminants, and constraints.*
Rule changes in this area have led to some incompatibilities; for example,
constrained subtypes of some access types are not permitted in Ada 2005.
* *Aggregates for limited types.*
The allowance of aggregates for limited types in Ada 2005 raises the
possibility of ambiguities in legal Ada 95 programs, since additional types
now need to be considered in expression resolution.
* *Fixed-point multiplication and division.*
Certain expressions involving '*' or '/' for a fixed-point type, which
were legal in Ada 95 and invoked the predefined versions of these operations,
are now ambiguous.
The ambiguity may be resolved either by applying a type conversion to the
expression, or by explicitly invoking the operation from package
`Standard`.
* *Return-by-reference types.*
The Ada 95 return-by-reference mechanism has been removed. Instead, the user
can declare a function returning a value from an anonymous access type.
.. _Implementation-dependent_characteristics:
Implementation-dependent characteristics
========================================
Although the Ada language defines the semantics of each construct as
precisely as practical, in some situations (for example for reasons of
efficiency, or where the effect is heavily dependent on the host or target
platform) the implementation is allowed some freedom. In porting Ada 83
code to GNAT, you need to be aware of whether / how the existing code
exercised such implementation dependencies. Such characteristics fall into
several categories, and GNAT offers specific support in assisting the
transition from certain Ada 83 compilers.
.. _Implementation-defined_pragmas:
Implementation-defined pragmas
------------------------------
Ada compilers are allowed to supplement the language-defined pragmas, and
these are a potential source of non-portability. All GNAT-defined pragmas
are described in the `Implementation Defined Pragmas` chapter of the
:title:`GNAT Reference Manual`, and these include several that are specifically
intended to correspond to other vendors' Ada 83 pragmas.
For migrating from VADS, the pragma `Use_VADS_Size` may be useful.
For compatibility with HP Ada 83, GNAT supplies the pragmas
`Extend_System`, `Ident`, `Inline_Generic`,
`Interface_Name`, `Passive`, `Suppress_All`,
and `Volatile`.
Other relevant pragmas include `External` and `Link_With`.
Some vendor-specific
Ada 83 pragmas (`Share_Generic`, `Subtitle`, and `Title`) are
recognized, thus
avoiding compiler rejection of units that contain such pragmas; they are not
relevant in a GNAT context and hence are not otherwise implemented.
.. _Implementation-defined_attributes:
Implementation-defined attributes
---------------------------------
Analogous to pragmas, the set of attributes may be extended by an
implementation. All GNAT-defined attributes are described in
`Implementation Defined Attributes` section of the
:title:`GNAT Reference Manual`, and these include several that are specifically intended
to correspond to other vendors' Ada 83 attributes. For migrating from VADS,
the attribute `VADS_Size` may be useful. For compatibility with HP
Ada 83, GNAT supplies the attributes `Bit`, `Machine_Size` and
`Type_Class`.
.. _Libraries:
Libraries
---------
Vendors may supply libraries to supplement the standard Ada API. If Ada 83
code uses vendor-specific libraries then there are several ways to manage
this in Ada 95 and later versions of the standard:
* If the source code for the libraries (specs and bodies) are
available, then the libraries can be migrated in the same way as the
application.
* If the source code for the specs but not the bodies are
available, then you can reimplement the bodies.
* Some features introduced by Ada 95 obviate the need for library support. For
example most Ada 83 vendors supplied a package for unsigned integers. The
Ada 95 modular type feature is the preferred way to handle this need, so
instead of migrating or reimplementing the unsigned integer package it may
be preferable to retrofit the application using modular types.
.. _Elaboration_order:
Elaboration order
-----------------
The implementation can choose any elaboration order consistent with the unit
dependency relationship. This freedom means that some orders can result in
Program_Error being raised due to an 'Access Before Elaboration': an attempt
to invoke a subprogram its body has been elaborated, or to instantiate a
generic before the generic body has been elaborated. By default GNAT
attempts to choose a safe order (one that will not encounter access before
elaboration problems) by implicitly inserting `Elaborate` or
`Elaborate_All` pragmas where
needed. However, this can lead to the creation of elaboration circularities
and a resulting rejection of the program by gnatbind. This issue is
thoroughly described in the `Elaboration Order Handling in GNAT` appendix
in the :title:`GNAT User's Guide`.
In brief, there are several
ways to deal with this situation:
* Modify the program to eliminate the circularities, e.g., by moving
elaboration-time code into explicitly-invoked procedures
* Constrain the elaboration order by including explicit `Elaborate_Body` or
`Elaborate` pragmas, and then inhibit the generation of implicit
`Elaborate_All`
pragmas either globally (as an effect of the *-gnatE* switch) or locally
(by selectively suppressing elaboration checks via pragma
`Suppress(Elaboration_Check)` when it is safe to do so).
.. _Target-specific_aspects:
Target-specific aspects
-----------------------
Low-level applications need to deal with machine addresses, data
representations, interfacing with assembler code, and similar issues. If
such an Ada 83 application is being ported to different target hardware (for
example where the byte endianness has changed) then you will need to
carefully examine the program logic; the porting effort will heavily depend
on the robustness of the original design. Moreover, Ada 95 (and thus
Ada 2005 and Ada 2012) are sometimes
incompatible with typical Ada 83 compiler practices regarding implicit
packing, the meaning of the Size attribute, and the size of access values.
GNAT's approach to these issues is described in :ref:`Representation_Clauses`.
.. _Compatibility_with_Other_Ada_Systems:
Compatibility with Other Ada Systems
====================================
If programs avoid the use of implementation dependent and
implementation defined features, as documented in the
:title:`Ada Reference Manual`, there should be a high degree of portability between
GNAT and other Ada systems. The following are specific items which
have proved troublesome in moving Ada 95 programs from GNAT to other Ada 95
compilers, but do not affect porting code to GNAT.
(As of January 2007, GNAT is the only compiler available for Ada 2005;
the following issues may or may not arise for Ada 2005 programs
when other compilers appear.)
* *Ada 83 Pragmas and Attributes*
Ada 95 compilers are allowed, but not required, to implement the missing
Ada 83 pragmas and attributes that are no longer defined in Ada 95.
GNAT implements all such pragmas and attributes, eliminating this as
a compatibility concern, but some other Ada 95 compilers reject these
pragmas and attributes.
* *Specialized Needs Annexes*
GNAT implements the full set of special needs annexes. At the
current time, it is the only Ada 95 compiler to do so. This means that
programs making use of these features may not be portable to other Ada
95 compilation systems.
* *Representation Clauses*
Some other Ada 95 compilers implement only the minimal set of
representation clauses required by the Ada 95 reference manual. GNAT goes
far beyond this minimal set, as described in the next section.
.. _Representation_Clauses:
Representation Clauses
======================
The Ada 83 reference manual was quite vague in describing both the minimal
required implementation of representation clauses, and also their precise
effects. Ada 95 (and thus also Ada 2005) are much more explicit, but the
minimal set of capabilities required is still quite limited.
GNAT implements the full required set of capabilities in
Ada 95 and Ada 2005, but also goes much further, and in particular
an effort has been made to be compatible with existing Ada 83 usage to the
greatest extent possible.
A few cases exist in which Ada 83 compiler behavior is incompatible with
the requirements in Ada 95 (and thus also Ada 2005). These are instances of
intentional or accidental dependence on specific implementation dependent
characteristics of these Ada 83 compilers. The following is a list of
the cases most likely to arise in existing Ada 83 code.
* *Implicit Packing*
Some Ada 83 compilers allowed a Size specification to cause implicit
packing of an array or record. This could cause expensive implicit
conversions for change of representation in the presence of derived
types, and the Ada design intends to avoid this possibility.
Subsequent AI's were issued to make it clear that such implicit
change of representation in response to a Size clause is inadvisable,
and this recommendation is represented explicitly in the Ada 95 (and Ada 2005)
Reference Manuals as implementation advice that is followed by GNAT.
The problem will show up as an error
message rejecting the size clause. The fix is simply to provide
the explicit pragma `Pack`, or for more fine tuned control, provide
a Component_Size clause.
* *Meaning of Size Attribute*
The Size attribute in Ada 95 (and Ada 2005) for discrete types is defined as
the minimal number of bits required to hold values of the type. For example,
on a 32-bit machine, the size of `Natural` will typically be 31 and not
32 (since no sign bit is required). Some Ada 83 compilers gave 31, and
some 32 in this situation. This problem will usually show up as a compile
time error, but not always. It is a good idea to check all uses of the
'Size attribute when porting Ada 83 code. The GNAT specific attribute
Object_Size can provide a useful way of duplicating the behavior of
some Ada 83 compiler systems.
* *Size of Access Types*
A common assumption in Ada 83 code is that an access type is in fact a pointer,
and that therefore it will be the same size as a System.Address value. This
assumption is true for GNAT in most cases with one exception. For the case of
a pointer to an unconstrained array type (where the bounds may vary from one
value of the access type to another), the default is to use a 'fat pointer',
which is represented as two separate pointers, one to the bounds, and one to
the array. This representation has a number of advantages, including improved
efficiency. However, it may cause some difficulties in porting existing Ada 83
code which makes the assumption that, for example, pointers fit in 32 bits on
a machine with 32-bit addressing.
To get around this problem, GNAT also permits the use of 'thin pointers' for
access types in this case (where the designated type is an unconstrained array
type). These thin pointers are indeed the same size as a System.Address value.
To specify a thin pointer, use a size clause for the type, for example:
.. code-block:: ada
type X is access all String;
for X'Size use Standard'Address_Size;
which will cause the type X to be represented using a single pointer.
When using this representation, the bounds are right behind the array.
This representation is slightly less efficient, and does not allow quite
such flexibility in the use of foreign pointers or in using the
Unrestricted_Access attribute to create pointers to non-aliased objects.
But for any standard portable use of the access type it will work in
a functionally correct manner and allow porting of existing code.
Note that another way of forcing a thin pointer representation
is to use a component size clause for the element size in an array,
or a record representation clause for an access field in a record.
See the documentation of Unrestricted_Access in the GNAT RM for a
full discussion of possible problems using this attribute in conjunction
with thin pointers.
.. _Compatibility_with_HP_Ada_83:
Compatibility with HP Ada 83
============================
All the HP Ada 83 pragmas and attributes are recognized, although only a subset
of them can sensibly be implemented. The description of pragmas in
:ref:`Implementation_Defined_Pragmas` indicates whether or not they are
applicable to GNAT.
* *Default floating-point representation*
In GNAT, the default floating-point format is IEEE, whereas in HP Ada 83,
it is VMS format.
* *System*
the package System in GNAT exactly corresponds to the definition in the
Ada 95 reference manual, which means that it excludes many of the
HP Ada 83 extensions. However, a separate package Aux_DEC is provided
that contains the additional definitions, and a special pragma,
Extend_System allows this package to be treated transparently as an
extension of package System.
.. _Implementation_Advice:
*********************
Implementation Advice
*********************
The main text of the Ada Reference Manual describes the required
behavior of all Ada compilers, and the GNAT compiler conforms to
these requirements.
In addition, there are sections throughout the Ada Reference Manual headed
by the phrase 'Implementation advice'. These sections are not normative,
i.e., they do not specify requirements that all compilers must
follow. Rather they provide advice on generally desirable behavior.
They are not requirements, because they describe behavior that cannot
be provided on all systems, or may be undesirable on some systems.
As far as practical, GNAT follows the implementation advice in
the Ada Reference Manual. Each such RM section corresponds to a section
in this chapter whose title specifies the
RM section number and paragraph number and the subject of
the advice. The contents of each section consists of the RM text within
quotation marks,
followed by the GNAT interpretation of the advice. Most often, this simply says
'followed', which means that GNAT follows the advice. However, in a
number of cases, GNAT deliberately deviates from this advice, in which
case the text describes what GNAT does and why.
.. index:: Error detection
RM 1.1.3(20): Error Detection
=============================
"If an implementation detects the use of an unsupported Specialized Needs
Annex feature at run time, it should raise `Program_Error` if
feasible."
Not relevant. All specialized needs annex features are either supported,
or diagnosed at compile time.
.. index:: Child Units
RM 1.1.3(31): Child Units
=========================
"If an implementation wishes to provide implementation-defined
extensions to the functionality of a language-defined library unit, it
should normally do so by adding children to the library unit."
Followed.
.. index:: Bounded errors
RM 1.1.5(12): Bounded Errors
============================
"If an implementation detects a bounded error or erroneous
execution, it should raise `Program_Error`."
Followed in all cases in which the implementation detects a bounded
error or erroneous execution. Not all such situations are detected at
runtime.
.. index:: Pragmas
.. _RM_2_8_16_Pragmas:
RM 2.8(16): Pragmas
===================
"Normally, implementation-defined pragmas should have no semantic effect
for error-free programs; that is, if the implementation-defined pragmas
are removed from a working program, the program should still be legal,
and should still have the same semantics."
The following implementation defined pragmas are exceptions to this
rule:
+--------------------+-------------------+
| Pragma | Explanation |
+====================+===================+
| *Abort_Defer* | Affects semantics |
+--------------------+-------------------+
|*Ada_83* | Affects legality |
+--------------------+-------------------+
|*Assert* | Affects semantics |
+--------------------+-------------------+
|*CPP_Class* | Affects semantics |
+--------------------+-------------------+
|*CPP_Constructor* | Affects semantics |
+--------------------+-------------------+
|*Debug* | Affects semantics |
+--------------------+-------------------+
|*Interface_Name* | Affects semantics |
+--------------------+-------------------+
|*Machine_Attribute* | Affects semantics |
+--------------------+-------------------+
|*Unimplemented_Unit*| Affects legality |
+--------------------+-------------------+
|*Unchecked_Union* | Affects semantics |
+--------------------+-------------------+
In each of the above cases, it is essential to the purpose of the pragma
that this advice not be followed. For details see
:ref:`Implementation_Defined_Pragmas`.
RM 2.8(17-19): Pragmas
======================
"Normally, an implementation should not define pragmas that can
make an illegal program legal, except as follows:
* A pragma used to complete a declaration, such as a pragma `Import`;
* A pragma used to configure the environment by adding, removing, or
replacing `library_items`."
See :ref:`RM_2_8_16_Pragmas`.
.. index:: Character Sets
.. index:: Alternative Character Sets
RM 3.5.2(5): Alternative Character Sets
=======================================
"If an implementation supports a mode with alternative interpretations
for `Character` and `Wide_Character`, the set of graphic
characters of `Character` should nevertheless remain a proper
subset of the set of graphic characters of `Wide_Character`. Any
character set 'localizations' should be reflected in the results of
the subprograms defined in the language-defined package
`Characters.Handling` (see A.3) available in such a mode. In a mode with
an alternative interpretation of `Character`, the implementation should
also support a corresponding change in what is a legal
`identifier_letter`."
Not all wide character modes follow this advice, in particular the JIS
and IEC modes reflect standard usage in Japan, and in these encoding,
the upper half of the Latin-1 set is not part of the wide-character
subset, since the most significant bit is used for wide character
encoding. However, this only applies to the external forms. Internally
there is no such restriction.
.. index:: Integer types
RM 3.5.4(28): Integer Types
===========================
"An implementation should support `Long_Integer` in addition to
`Integer` if the target machine supports 32-bit (or longer)
arithmetic. No other named integer subtypes are recommended for package
`Standard`. Instead, appropriate named integer subtypes should be
provided in the library package `Interfaces` (see B.2)."
`Long_Integer` is supported. Other standard integer types are supported
so this advice is not fully followed. These types
are supported for convenient interface to C, and so that all hardware
types of the machine are easily available.
RM 3.5.4(29): Integer Types
===========================
"An implementation for a two's complement machine should support
modular types with a binary modulus up to ``System.Max_Int*2+2``. An
implementation should support a non-binary modules up to `Integer'Last`."
Followed.
.. index:: Enumeration values
RM 3.5.5(8): Enumeration Values
===============================
"For the evaluation of a call on ``S'Pos`` for an enumeration
subtype, if the value of the operand does not correspond to the internal
code for any enumeration literal of its type (perhaps due to an
un-initialized variable), then the implementation should raise
`Program_Error`. This is particularly important for enumeration
types with noncontiguous internal codes specified by an
enumeration_representation_clause."
Followed.
.. index:: Float types
RM 3.5.7(17): Float Types
=========================
"An implementation should support `Long_Float` in addition to
`Float` if the target machine supports 11 or more digits of
precision. No other named floating point subtypes are recommended for
package `Standard`. Instead, appropriate named floating point subtypes
should be provided in the library package `Interfaces` (see B.2)."
`Short_Float` and `Long_Long_Float` are also provided. The
former provides improved compatibility with other implementations
supporting this type. The latter corresponds to the highest precision
floating-point type supported by the hardware. On most machines, this
will be the same as `Long_Float`, but on some machines, it will
correspond to the IEEE extended form. The notable case is all ia32
(x86) implementations, where `Long_Long_Float` corresponds to
the 80-bit extended precision format supported in hardware on this
processor. Note that the 128-bit format on SPARC is not supported,
since this is a software rather than a hardware format.
.. index:: Multidimensional arrays
.. index:: Arrays, multidimensional
RM 3.6.2(11): Multidimensional Arrays
=====================================
"An implementation should normally represent multidimensional arrays in
row-major order, consistent with the notation used for multidimensional
array aggregates (see 4.3.3). However, if a pragma `Convention`
(`Fortran`, ...) applies to a multidimensional array type, then
column-major order should be used instead (see B.5, `Interfacing with Fortran`)."
Followed.
.. index:: Duration'Small
RM 9.6(30-31): Duration'Small
=============================
"Whenever possible in an implementation, the value of `Duration'Small`
should be no greater than 100 microseconds."
Followed. (`Duration'Small` = 10**(-9)).
"The time base for `delay_relative_statements` should be monotonic;
it need not be the same time base as used for `Calendar.Clock`."
Followed.
RM 10.2.1(12): Consistent Representation
========================================
"In an implementation, a type declared in a pre-elaborated package should
have the same representation in every elaboration of a given version of
the package, whether the elaborations occur in distinct executions of
the same program, or in executions of distinct programs or partitions
that include the given version."
Followed, except in the case of tagged types. Tagged types involve
implicit pointers to a local copy of a dispatch table, and these pointers
have representations which thus depend on a particular elaboration of the
package. It is not easy to see how it would be possible to follow this
advice without severely impacting efficiency of execution.
.. index:: Exception information
RM 11.4.1(19): Exception Information
====================================
"`Exception_Message` by default and `Exception_Information`
should produce information useful for
debugging. `Exception_Message` should be short, about one
line. `Exception_Information` can be long. `Exception_Message`
should not include the
`Exception_Name`. `Exception_Information` should include both
the `Exception_Name` and the `Exception_Message`."
Followed. For each exception that doesn't have a specified
`Exception_Message`, the compiler generates one containing the location
of the raise statement. This location has the form 'file_name:line', where
file_name is the short file name (without path information) and line is the line
number in the file. Note that in the case of the Zero Cost Exception
mechanism, these messages become redundant with the Exception_Information that
contains a full backtrace of the calling sequence, so they are disabled.
To disable explicitly the generation of the source location message, use the
Pragma `Discard_Names`.
.. index:: Suppression of checks
.. index:: Checks, suppression of
RM 11.5(28): Suppression of Checks
==================================
"The implementation should minimize the code executed for checks that
have been suppressed."
Followed.
.. index:: Representation clauses
RM 13.1 (21-24): Representation Clauses
=======================================
"The recommended level of support for all representation items is
qualified as follows:
An implementation need not support representation items containing
non-static expressions, except that an implementation should support a
representation item for a given entity if each non-static expression in
the representation item is a name that statically denotes a constant
declared before the entity."
Followed. In fact, GNAT goes beyond the recommended level of support
by allowing nonstatic expressions in some representation clauses even
without the need to declare constants initialized with the values of
such expressions.
For example:
.. code-block:: ada
X : Integer;
Y : Float;
for Y'Address use X'Address;>>
"An implementation need not support a specification for the `Size`
for a given composite subtype, nor the size or storage place for an
object (including a component) of a given composite subtype, unless the
constraints on the subtype and its composite subcomponents (if any) are
all static constraints."
Followed. Size Clauses are not permitted on non-static components, as
described above.
"An aliased component, or a component whose type is by-reference, should
always be allocated at an addressable location."
Followed.
.. index:: Packed types
RM 13.2(6-8): Packed Types
==========================
"If a type is packed, then the implementation should try to minimize
storage allocated to objects of the type, possibly at the expense of
speed of accessing components, subject to reasonable complexity in
addressing calculations.
The recommended level of support pragma `Pack` is:
For a packed record type, the components should be packed as tightly as
possible subject to the Sizes of the component subtypes, and subject to
any `record_representation_clause` that applies to the type; the
implementation may, but need not, reorder components or cross aligned
word boundaries to improve the packing. A component whose `Size` is
greater than the word size may be allocated an integral number of words."
Followed. Tight packing of arrays is supported for all component sizes
up to 64-bits. If the array component size is 1 (that is to say, if
the component is a boolean type or an enumeration type with two values)
then values of the type are implicitly initialized to zero. This
happens both for objects of the packed type, and for objects that have a
subcomponent of the packed type.
"An implementation should support Address clauses for imported
subprograms."
Followed.
.. index:: Address clauses
RM 13.3(14-19): Address Clauses
===============================
"For an array `X`, ``X'Address`` should point at the first
component of the array, and not at the array bounds."
Followed.
"The recommended level of support for the `Address` attribute is:
``X'Address`` should produce a useful result if `X` is an
object that is aliased or of a by-reference type, or is an entity whose
`Address` has been specified."
Followed. A valid address will be produced even if none of those
conditions have been met. If necessary, the object is forced into
memory to ensure the address is valid.
"An implementation should support `Address` clauses for imported
subprograms."
Followed.
"Objects (including subcomponents) that are aliased or of a by-reference
type should be allocated on storage element boundaries."
Followed.
"If the `Address` of an object is specified, or it is imported or exported,
then the implementation should not perform optimizations based on
assumptions of no aliases."
Followed.
.. index:: Alignment clauses
RM 13.3(29-35): Alignment Clauses
=================================
"The recommended level of support for the `Alignment` attribute for
subtypes is:
An implementation should support specified Alignments that are factors
and multiples of the number of storage elements per word, subject to the
following:"
Followed.
"An implementation need not support specified Alignments for
combinations of Sizes and Alignments that cannot be easily
loaded and stored by available machine instructions."
Followed.
"An implementation need not support specified Alignments that are
greater than the maximum `Alignment` the implementation ever returns by
default."
Followed.
"The recommended level of support for the `Alignment` attribute for
objects is:
Same as above, for subtypes, but in addition:"
Followed.
"For stand-alone library-level objects of statically constrained
subtypes, the implementation should support all alignments
supported by the target linker. For example, page alignment is likely to
be supported for such objects, but not for subtypes."
Followed.
.. index:: Size clauses
RM 13.3(42-43): Size Clauses
============================
"The recommended level of support for the `Size` attribute of
objects is:
A `Size` clause should be supported for an object if the specified
`Size` is at least as large as its subtype's `Size`, and
corresponds to a size in storage elements that is a multiple of the
object's `Alignment` (if the `Alignment` is nonzero)."
Followed.
RM 13.3(50-56): Size Clauses
============================
"If the `Size` of a subtype is specified, and allows for efficient
independent addressability (see 9.10) on the target architecture, then
the `Size` of the following objects of the subtype should equal the
`Size` of the subtype:
Aliased objects (including components)."
Followed.
"`Size` clause on a composite subtype should not affect the
internal layout of components."
Followed. But note that this can be overridden by use of the implementation
pragma Implicit_Packing in the case of packed arrays.
"The recommended level of support for the `Size` attribute of subtypes is:
The `Size` (if not specified) of a static discrete or fixed point
subtype should be the number of bits needed to represent each value
belonging to the subtype using an unbiased representation, leaving space
for a sign bit only if the subtype contains negative values. If such a
subtype is a first subtype, then an implementation should support a
specified `Size` for it that reflects this representation."
Followed.
"For a subtype implemented with levels of indirection, the `Size`
should include the size of the pointers, but not the size of what they
point at."
Followed.
.. index:: Component_Size clauses
RM 13.3(71-73): Component Size Clauses
======================================
"The recommended level of support for the `Component_Size`
attribute is:
An implementation need not support specified `Component_Sizes` that are
less than the `Size` of the component subtype."
Followed.
"An implementation should support specified Component_Sizes that
are factors and multiples of the word size. For such
Component_Sizes, the array should contain no gaps between
components. For other Component_Sizes (if supported), the array
should contain no gaps between components when packing is also
specified; the implementation should forbid this combination in cases
where it cannot support a no-gaps representation."
Followed.
.. index:: Enumeration representation clauses
.. index:: Representation clauses, enumeration
RM 13.4(9-10): Enumeration Representation Clauses
=================================================
"The recommended level of support for enumeration representation clauses
is:
An implementation need not support enumeration representation clauses
for boolean types, but should at minimum support the internal codes in
the range `System.Min_Int .. System.Max_Int`."
Followed.
.. index:: Record representation clauses
.. index:: Representation clauses, records
RM 13.5.1(17-22): Record Representation Clauses
===============================================
"The recommended level of support for
`record_representation_clauses` is:
An implementation should support storage places that can be extracted
with a load, mask, shift sequence of machine code, and set with a load,
shift, mask, store sequence, given the available machine instructions
and run-time model."
Followed.
"A storage place should be supported if its size is equal to the
`Size` of the component subtype, and it starts and ends on a
boundary that obeys the `Alignment` of the component subtype."
Followed.
"If the default bit ordering applies to the declaration of a given type,
then for a component whose subtype's `Size` is less than the word
size, any storage place that does not cross an aligned word boundary
should be supported."
Followed.
"An implementation may reserve a storage place for the tag field of a
tagged type, and disallow other components from overlapping that place."
Followed. The storage place for the tag field is the beginning of the tagged
record, and its size is Address'Size. GNAT will reject an explicit component
clause for the tag field.
"An implementation need not support a `component_clause` for a
component of an extension part if the storage place is not after the
storage places of all components of the parent type, whether or not
those storage places had been specified."
Followed. The above advice on record representation clauses is followed,
and all mentioned features are implemented.
.. index:: Storage place attributes
RM 13.5.2(5): Storage Place Attributes
======================================
"If a component is represented using some form of pointer (such as an
offset) to the actual data of the component, and this data is contiguous
with the rest of the object, then the storage place attributes should
reflect the place of the actual data, not the pointer. If a component is
allocated discontinuously from the rest of the object, then a warning
should be generated upon reference to one of its storage place
attributes."
Followed. There are no such components in GNAT.
.. index:: Bit ordering
RM 13.5.3(7-8): Bit Ordering
============================
"The recommended level of support for the non-default bit ordering is:
If `Word_Size` = `Storage_Unit`, then the implementation
should support the non-default bit ordering in addition to the default
bit ordering."
Followed. Word size does not equal storage size in this implementation.
Thus non-default bit ordering is not supported.
.. index:: Address, as private type
RM 13.7(37): Address as Private
===============================
"`Address` should be of a private type."
Followed.
.. index:: Operations, on `Address`
.. index:: Address, operations of
RM 13.7.1(16): Address Operations
=================================
"Operations in `System` and its children should reflect the target
environment semantics as closely as is reasonable. For example, on most
machines, it makes sense for address arithmetic to 'wrap around'.
Operations that do not make sense should raise `Program_Error`."
Followed. Address arithmetic is modular arithmetic that wraps around. No
operation raises `Program_Error`, since all operations make sense.
.. index:: Unchecked conversion
RM 13.9(14-17): Unchecked Conversion
====================================
"The `Size` of an array object should not include its bounds; hence,
the bounds should not be part of the converted data."
Followed.
"The implementation should not generate unnecessary run-time checks to
ensure that the representation of `S` is a representation of the
target type. It should take advantage of the permission to return by
reference when possible. Restrictions on unchecked conversions should be
avoided unless required by the target environment."
Followed. There are no restrictions on unchecked conversion. A warning is
generated if the source and target types do not have the same size since
the semantics in this case may be target dependent.
"The recommended level of support for unchecked conversions is:
Unchecked conversions should be supported and should be reversible in
the cases where this clause defines the result. To enable meaningful use
of unchecked conversion, a contiguous representation should be used for
elementary subtypes, for statically constrained array subtypes whose
component subtype is one of the subtypes described in this paragraph,
and for record subtypes without discriminants whose component subtypes
are described in this paragraph."
Followed.
.. index:: Heap usage, implicit
RM 13.11(23-25): Implicit Heap Usage
====================================
"An implementation should document any cases in which it dynamically
allocates heap storage for a purpose other than the evaluation of an
allocator."
Followed, the only other points at which heap storage is dynamically
allocated are as follows:
*
At initial elaboration time, to allocate dynamically sized global
objects.
*
To allocate space for a task when a task is created.
*
To extend the secondary stack dynamically when needed. The secondary
stack is used for returning variable length results.
..
"A default (implementation-provided) storage pool for an
access-to-constant type should not have overhead to support deallocation of
individual objects."
Followed.
"A storage pool for an anonymous access type should be created at the
point of an allocator for the type, and be reclaimed when the designated
object becomes inaccessible."
Followed.
.. index:: Unchecked deallocation
RM 13.11.2(17): Unchecked Deallocation
======================================
"For a standard storage pool, `Free` should actually reclaim the
storage."
Followed.
.. index:: Stream oriented attributes
RM 13.13.2(17): Stream Oriented Attributes
==========================================
"If a stream element is the same size as a storage element, then the
normal in-memory representation should be used by `Read` and
`Write` for scalar objects. Otherwise, `Read` and `Write`
should use the smallest number of stream elements needed to represent
all values in the base range of the scalar type."
Followed. By default, GNAT uses the interpretation suggested by AI-195,
which specifies using the size of the first subtype.
However, such an implementation is based on direct binary
representations and is therefore target- and endianness-dependent.
To address this issue, GNAT also supplies an alternate implementation
of the stream attributes `Read` and `Write`,
which uses the target-independent XDR standard representation
for scalar types.
.. index:: XDR representation
.. index:: Read attribute
.. index:: Write attribute
.. index:: Stream oriented attributes
The XDR implementation is provided as an alternative body of the
`System.Stream_Attributes` package, in the file
:file:`s-stratt-xdr.adb` in the GNAT library.
There is no :file:`s-stratt-xdr.ads` file.
In order to install the XDR implementation, do the following:
* Replace the default implementation of the
`System.Stream_Attributes` package with the XDR implementation.
For example on a Unix platform issue the commands:
.. code-block:: sh
$ mv s-stratt.adb s-stratt-default.adb
$ mv s-stratt-xdr.adb s-stratt.adb
*
Rebuild the GNAT run-time library as documented in
the `GNAT and Libraries` section of the :title:`GNAT User's Guide`.
RM A.1(52): Names of Predefined Numeric Types
=============================================
"If an implementation provides additional named predefined integer types,
then the names should end with ``Integer`` as in
``Long_Integer``. If an implementation provides additional named
predefined floating point types, then the names should end with
``Float`` as in ``Long_Float``."
Followed.
.. index:: Ada.Characters.Handling
RM A.3.2(49): `Ada.Characters.Handling`
=======================================
"If an implementation provides a localized definition of `Character`
or `Wide_Character`, then the effects of the subprograms in
`Characters.Handling` should reflect the localizations.
See also 3.5.2."
Followed. GNAT provides no such localized definitions.
.. index:: Bounded-length strings
RM A.4.4(106): Bounded-Length String Handling
=============================================
"Bounded string objects should not be implemented by implicit pointers
and dynamic allocation."
Followed. No implicit pointers or dynamic allocation are used.
.. index:: Random number generation
RM A.5.2(46-47): Random Number Generation
=========================================
"Any storage associated with an object of type `Generator` should be
reclaimed on exit from the scope of the object."
Followed.
"If the generator period is sufficiently long in relation to the number
of distinct initiator values, then each possible value of
`Initiator` passed to `Reset` should initiate a sequence of
random numbers that does not, in a practical sense, overlap the sequence
initiated by any other value. If this is not possible, then the mapping
between initiator values and generator states should be a rapidly
varying function of the initiator value."
Followed. The generator period is sufficiently long for the first
condition here to hold true.
.. index:: Get_Immediate
RM A.10.7(23): `Get_Immediate`
==============================
"The `Get_Immediate` procedures should be implemented with
unbuffered input. For a device such as a keyboard, input should be
available if a key has already been typed, whereas for a disk
file, input should always be available except at end of file. For a file
associated with a keyboard-like device, any line-editing features of the
underlying operating system should be disabled during the execution of
`Get_Immediate`."
Followed on all targets except VxWorks. For VxWorks, there is no way to
provide this functionality that does not result in the input buffer being
flushed before the `Get_Immediate` call. A special unit
`Interfaces.Vxworks.IO` is provided that contains routines to enable
this functionality.
.. index:: Export
RM B.1(39-41): Pragma `Export`
==============================
"If an implementation supports pragma `Export` to a given 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 are called."
Followed.
"Automatic elaboration of pre-elaborated packages should be
provided when pragma `Export` is supported."
Followed when the main program is in Ada. If the main program is in a
foreign language, then
`adainit` must be called to elaborate pre-elaborated
packages.
"For each supported convention `L` other than `Intrinsic`, an
implementation should support `Import` and `Export` pragmas
for objects of `L`-compatible types and for subprograms, and pragma
`Convention` for `L`-eligible types and for subprograms,
presuming the other language has corresponding features. Pragma
`Convention` need not be supported for scalar types."
Followed.
.. index:: Package Interfaces
.. index:: Interfaces
RM B.2(12-13): Package `Interfaces`
===================================
"For each implementation-defined convention identifier, there should be a
child package of package Interfaces with the corresponding name. This
package should contain any declarations that would be useful for
interfacing to the language (implementation) represented by the
convention. Any declarations useful for interfacing to any language on
the given hardware architecture should be provided directly in
`Interfaces`."
Followed.
"An implementation supporting an interface to C, COBOL, or Fortran should
provide the corresponding package or packages described in the following
clauses."
Followed. GNAT provides all the packages described in this section.
.. index:: C, interfacing with
RM B.3(63-71): Interfacing with C
=================================
"An implementation should support the following interface correspondences
between Ada and C."
Followed.
"An Ada procedure corresponds to a void-returning C function."
Followed.
"An Ada function corresponds to a non-void C function."
Followed.
"An Ada `in` scalar parameter is passed as a scalar argument to a C
function."
Followed.
"An Ada `in` parameter of an access-to-object type with designated
type `T` is passed as a ``t*`` argument to a C function,
where ``t`` is the C type corresponding to the Ada type `T`."
Followed.
"An Ada access `T` parameter, or an Ada `out` or `in out`
parameter of an elementary type `T`, is passed as a ``t*``
argument to a C function, where ``t`` is the C type corresponding to
the Ada type `T`. In the case of an elementary `out` or
`in out` parameter, a pointer to a temporary copy is used to
preserve by-copy semantics."
Followed.
"An Ada parameter of a record type `T`, of any mode, is passed as a
``t*`` argument to a C function, where ``t`` is the C
structure corresponding to the Ada type `T`."
Followed. This convention may be overridden by the use of the C_Pass_By_Copy
pragma, or Convention, or by explicitly specifying the mechanism for a given
call using an extended import or export pragma.
"An Ada parameter of an array type with component type `T`, of any
mode, is passed as a ``t*`` argument to a C function, where
``t`` is the C type corresponding to the Ada type `T`."
Followed.
"An Ada parameter of an access-to-subprogram type is passed as a pointer
to a C function whose prototype corresponds to the designated
subprogram's specification."
Followed.
.. index:: COBOL, interfacing with
RM B.4(95-98): Interfacing with COBOL
=====================================
"An Ada implementation should support the following interface
correspondences between Ada and COBOL."
Followed.
"An Ada access `T` parameter is passed as a ``BY REFERENCE`` data item of
the COBOL type corresponding to `T`."
Followed.
"An Ada in scalar parameter is passed as a ``BY CONTENT`` data item of
the corresponding COBOL type."
Followed.
"Any other Ada parameter is passed as a ``BY REFERENCE`` data item of the
COBOL type corresponding to the Ada parameter type; for scalars, a local
copy is used if necessary to ensure by-copy semantics."
Followed.
.. index:: Fortran, interfacing with
RM B.5(22-26): Interfacing with Fortran
=======================================
"An Ada implementation should support the following interface
correspondences between Ada and Fortran:"
Followed.
"An Ada procedure corresponds to a Fortran subroutine."
Followed.
"An Ada function corresponds to a Fortran function."
Followed.
"An Ada parameter of an elementary, array, or record type `T` is
passed as a `T` argument to a Fortran procedure, where `T` is
the Fortran type corresponding to the Ada type `T`, and where the
INTENT attribute of the corresponding dummy argument matches the Ada
formal parameter mode; the Fortran implementation's parameter passing
conventions are used. For elementary types, a local copy is used if
necessary to ensure by-copy semantics."
Followed.
"An Ada parameter of an access-to-subprogram type is passed as a
reference to a Fortran procedure whose interface corresponds to the
designated subprogram's specification."
Followed.
.. index:: Machine operations
RM C.1(3-5): Access to Machine Operations
=========================================
"The machine code or intrinsic support should allow access to all
operations normally available to assembly language programmers for the
target environment, including privileged instructions, if any."
Followed.
"The interfacing pragmas (see Annex B) should support interface to
assembler; the default assembler should be associated with the
convention identifier `Assembler`."
Followed.
"If an entity is exported to assembly language, then the implementation
should allocate it at an addressable location, and should ensure that it
is retained by the linking process, even if not otherwise referenced
from the Ada code. The implementation should assume that any call to a
machine code or assembler subprogram is allowed to read or update every
object that is specified as exported."
Followed.
RM C.1(10-16): Access to Machine Operations
===========================================
"The implementation should ensure that little or no overhead is
associated with calling intrinsic and machine-code subprograms."
Followed for both intrinsics and machine-code subprograms.
"It is recommended that intrinsic subprograms be provided for convenient
access to any machine operations that provide special capabilities or
efficiency and that are not otherwise available through the language
constructs."
Followed. A full set of machine operation intrinsic subprograms is provided.
"Atomic read-modify-write operations---e.g., test and set, compare and
swap, decrement and test, enqueue/dequeue."
Followed on any target supporting such operations.
"Standard numeric functions---e.g.:, sin, log."
Followed on any target supporting such operations.
"String manipulation operations---e.g.:, translate and test."
Followed on any target supporting such operations.
"Vector operations---e.g.:, compare vector against thresholds."
Followed on any target supporting such operations.
"Direct operations on I/O ports."
Followed on any target supporting such operations.
.. index:: Interrupt support
RM C.3(28): Interrupt Support
=============================
"If the `Ceiling_Locking` policy is not in effect, the
implementation should provide means for the application to specify which
interrupts are to be blocked during protected actions, if the underlying
system allows for a finer-grain control of interrupt blocking."
Followed. The underlying system does not allow for finer-grain control
of interrupt blocking.
.. index:: Protected procedure handlers
RM C.3.1(20-21): Protected Procedure Handlers
=============================================
"Whenever possible, the implementation should allow interrupt handlers to
be called directly by the hardware."
Followed on any target where the underlying operating system permits
such direct calls.
"Whenever practical, violations of any
implementation-defined restrictions should be detected before run time."
Followed. Compile time warnings are given when possible.
.. index:: Package `Interrupts`
.. index:: Interrupts
RM C.3.2(25): Package `Interrupts`
==================================
"If implementation-defined forms of interrupt handler procedures are
supported, such as protected procedures with parameters, then for each
such form of a handler, a type analogous to `Parameterless_Handler`
should be specified in a child package of `Interrupts`, with the
same operations as in the predefined package Interrupts."
Followed.
.. index:: Pre-elaboration requirements
RM C.4(14): Pre-elaboration Requirements
========================================
"It is recommended that pre-elaborated packages be implemented in such a
way that there should be little or no code executed at run time for the
elaboration of entities not already covered by the Implementation
Requirements."
Followed. Executable code is generated in some cases, e.g., loops
to initialize large arrays.
RM C.5(8): Pragma `Discard_Names`
=================================
"If the pragma applies to an entity, then the implementation should
reduce the amount of storage used for storing names associated with that
entity."
Followed.
.. index:: Package Task_Attributes
.. index:: Task_Attributes
RM C.7.2(30): The Package Task_Attributes
=========================================
"Some implementations are targeted to domains in which memory use at run
time must be completely deterministic. For such implementations, it is
recommended that the storage for task attributes will be pre-allocated
statically and not from the heap. This can be accomplished by either
placing restrictions on the number and the size of the task's
attributes, or by using the pre-allocated storage for the first `N`
attribute objects, and the heap for the others. In the latter case,
`N` should be documented."
Not followed. This implementation is not targeted to such a domain.
.. index:: Locking Policies
RM D.3(17): Locking Policies
============================
"The implementation should use names that end with ``_Locking`` for
locking policies defined by the implementation."
Followed. Two implementation-defined locking policies are defined,
whose names (`Inheritance_Locking` and
`Concurrent_Readers_Locking`) follow this suggestion.
.. index:: Entry queuing policies
RM D.4(16): Entry Queuing Policies
==================================
"Names that end with ``_Queuing`` should be used
for all implementation-defined queuing policies."
Followed. No such implementation-defined queuing policies exist.
.. index:: Preemptive abort
RM D.6(9-10): Preemptive Abort
==============================
"Even though the `abort_statement` is included in the list of
potentially blocking operations (see 9.5.1), it is recommended that this
statement be implemented in a way that never requires the task executing
the `abort_statement` to block."
Followed.
"On a multi-processor, the delay associated with aborting a task on
another processor should be bounded; the implementation should use
periodic polling, if necessary, to achieve this."
Followed.
.. index:: Tasking restrictions
RM D.7(21): Tasking Restrictions
================================
"When feasible, the implementation should take advantage of the specified
restrictions to produce a more efficient implementation."
GNAT currently takes advantage of these restrictions by providing an optimized
run time when the Ravenscar profile and the GNAT restricted run time set
of restrictions are specified. See pragma `Profile (Ravenscar)` and
pragma `Profile (Restricted)` for more details.
.. index:: Time, monotonic
RM D.8(47-49): Monotonic Time
=============================
"When appropriate, implementations should provide configuration
mechanisms to change the value of `Tick`."
Such configuration mechanisms are not appropriate to this implementation
and are thus not supported.
"It is recommended that `Calendar.Clock` and `Real_Time.Clock`
be implemented as transformations of the same time base."
Followed.
"It is recommended that the best time base which exists in
the underlying system be available to the application through
`Clock`. `Best` may mean highest accuracy or largest range."
Followed.
.. index:: Partition communication subsystem
.. index:: PCS
RM E.5(28-29): Partition Communication Subsystem
================================================
"Whenever possible, the PCS on the called partition should allow for
multiple tasks to call the RPC-receiver with different messages and
should allow them to block until the corresponding subprogram body
returns."
Followed by GLADE, a separately supplied PCS that can be used with
GNAT.
"The `Write` operation on a stream of type `Params_Stream_Type`
should raise `Storage_Error` if it runs out of space trying to
write the `Item` into the stream."
Followed by GLADE, a separately supplied PCS that can be used with
GNAT.
.. index:: COBOL support
RM F(7): COBOL Support
======================
"If COBOL (respectively, C) is widely supported in the target
environment, implementations supporting the Information Systems Annex
should provide the child package `Interfaces.COBOL` (respectively,
`Interfaces.C`) specified in Annex B and should support a
`convention_identifier` of COBOL (respectively, C) in the interfacing
pragmas (see Annex B), thus allowing Ada programs to interface with
programs written in that language."
Followed.
.. index:: Decimal radix support
RM F.1(2): Decimal Radix Support
================================
"Packed decimal should be used as the internal representation for objects
of subtype `S` when `S`'Machine_Radix = 10."
Not followed. GNAT ignores `S`'Machine_Radix and always uses binary
representations.
.. index:: Numerics
RM G: Numerics
==============
"If Fortran (respectively, C) is widely supported in the target
environment, implementations supporting the Numerics Annex
should provide the child package `Interfaces.Fortran` (respectively,
`Interfaces.C`) specified in Annex B and should support a
`convention_identifier` of Fortran (respectively, C) in the interfacing
pragmas (see Annex B), thus allowing Ada programs to interface with
programs written in that language."
Followed.
.. index:: Complex types
RM G.1.1(56-58): Complex Types
==============================
"Because the usual mathematical meaning of multiplication of a complex
operand and a real operand is that of the scaling of both components of
the former by the latter, an implementation should not perform this
operation by first promoting the real operand to complex type and then
performing a full complex multiplication. In systems that, in the
future, support an Ada binding to IEC 559:1989, the latter technique
will not generate the required result when one of the components of the
complex operand is infinite. (Explicit multiplication of the infinite
component by the zero component obtained during promotion yields a NaN
that propagates into the final result.) Analogous advice applies in the
case of multiplication of a complex operand and a pure-imaginary
operand, and in the case of division of a complex operand by a real or
pure-imaginary operand."
Not followed.
"Similarly, because the usual mathematical meaning of addition of a
complex operand and a real operand is that the imaginary operand remains
unchanged, an implementation should not perform this operation by first
promoting the real operand to complex type and then performing a full
complex addition. In implementations in which the `Signed_Zeros`
attribute of the component type is `True` (and which therefore
conform to IEC 559:1989 in regard to the handling of the sign of zero in
predefined arithmetic operations), the latter technique will not
generate the required result when the imaginary component of the complex
operand is a negatively signed zero. (Explicit addition of the negative
zero to the zero obtained during promotion yields a positive zero.)
Analogous advice applies in the case of addition of a complex operand
and a pure-imaginary operand, and in the case of subtraction of a
complex operand and a real or pure-imaginary operand."
Not followed.
"Implementations in which `Real'Signed_Zeros` is `True` should
attempt to provide a rational treatment of the signs of zero results and
result components. As one example, the result of the `Argument`
function should have the sign of the imaginary component of the
parameter `X` when the point represented by that parameter lies on
the positive real axis; as another, the sign of the imaginary component
of the `Compose_From_Polar` function should be the same as
(respectively, the opposite of) that of the `Argument` parameter when that
parameter has a value of zero and the `Modulus` parameter has a
nonnegative (respectively, negative) value."
Followed.
.. index:: Complex elementary functions
RM G.1.2(49): Complex Elementary Functions
==========================================
"Implementations in which `Complex_Types.Real'Signed_Zeros` is
`True` should attempt to provide a rational treatment of the signs
of zero results and result components. For example, many of the complex
elementary functions have components that are odd functions of one of
the parameter components; in these cases, the result component should
have the sign of the parameter component at the origin. Other complex
elementary functions have zero components whose sign is opposite that of
a parameter component at the origin, or is always positive or always
negative."
Followed.
.. index:: Accuracy requirements
RM G.2.4(19): Accuracy Requirements
===================================
"The versions of the forward trigonometric functions without a
`Cycle` parameter should not be implemented by calling the
corresponding version with a `Cycle` parameter of
`2.0*Numerics.Pi`, since this will not provide the required
accuracy in some portions of the domain. For the same reason, the
version of `Log` without a `Base` parameter should not be
implemented by calling the corresponding version with a `Base`
parameter of `Numerics.e`."
Followed.
.. index:: Complex arithmetic accuracy
.. index:: Accuracy, complex arithmetic
RM G.2.6(15): Complex Arithmetic Accuracy
=========================================
"The version of the `Compose_From_Polar` function without a
`Cycle` parameter should not be implemented by calling the
corresponding version with a `Cycle` parameter of
`2.0*Numerics.Pi`, since this will not provide the required
accuracy in some portions of the domain."
Followed.
.. index:: Sequential elaboration policy
RM H.6(15/2): Pragma Partition_Elaboration_Policy
=================================================
"If the partition elaboration policy is `Sequential` and the
Environment task becomes permanently blocked during elaboration then the
partition is deadlocked and it is recommended that the partition be
immediately terminated."
Not followed.
.. _Implementation_Defined_Aspects:
******************************
Implementation Defined Aspects
******************************
Ada defines (throughout the Ada 2012 reference manual, summarized
in Annex K) a set of aspects that can be specified for certain entities.
These language defined aspects are implemented in GNAT in Ada 2012 mode
and work as described in the Ada 2012 Reference Manual.
In addition, Ada 2012 allows implementations to define additional aspects
whose meaning is defined by the implementation. GNAT provides
a number of these implementation-defined aspects which can be used
to extend and enhance the functionality of the compiler. This section of
the GNAT reference manual describes these additional aspects.
Note that any program using these aspects may not be portable to
other compilers (although GNAT implements this set of aspects on all
platforms). Therefore if portability to other compilers is an important
consideration, you should minimize the use of these aspects.
Note that for many of these aspects, the effect is essentially similar
to the use of a pragma or attribute specification with the same name
applied to the entity. For example, if we write:
.. code-block:: ada
type R is range 1 .. 100
with Value_Size => 10;
then the effect is the same as:
.. code-block:: ada
type R is range 1 .. 100;
for R'Value_Size use 10;
and if we write:
.. code-block:: ada
type R is new Integer
with Shared => True;
then the effect is the same as:
.. code-block:: ada
type R is new Integer;
pragma Shared (R);
In the documentation below, such cases are simply marked
as being boolean aspects equivalent to the corresponding pragma
or attribute definition clause.
Aspect Abstract_State
=====================
.. index:: Abstract_State
This aspect is equivalent to pragma `Abstract_State`.
Annotate
========
.. index:: Annotate
There are three forms of this aspect (where ID is an identifier,
and ARG is a general expression).
*Annotate => ID*
Equivalent to `pragma Annotate (ID, Entity => Name);`
*Annotate => (ID)*
Equivalent to `pragma Annotate (ID, Entity => Name);`
*Annotate => (ID ,ID {, ARG})*
Equivalent to `pragma Annotate (ID, ID {, ARG}, Entity => Name);`
Aspect Async_Readers
====================
.. index:: Async_Readers
This boolean aspect is equivalent to pragma `Async_Readers`.
Aspect Async_Writers
====================
.. index:: Async_Writers
This boolean aspect is equivalent to pragma `Async_Writers`.
Aspect Contract_Cases
=====================
.. index:: Contract_Cases
This aspect is equivalent to pragma `Contract_Cases`, the sequence
of clauses being enclosed in parentheses so that syntactically it is an
aggregate.
Aspect Depends
==============
.. index:: Depends
This aspect is equivalent to pragma `Depends`.
Aspect Dimension
================
.. index:: Dimension
The `Dimension` aspect is used to specify the dimensions of a given
subtype of a dimensioned numeric type. The aspect also specifies a symbol
used when doing formatted output of dimensioned quantities. The syntax is::
with Dimension =>
([Symbol =>] SYMBOL, DIMENSION_VALUE {, DIMENSION_Value})
SYMBOL ::= STRING_LITERAL | CHARACTER_LITERAL
DIMENSION_VALUE ::=
RATIONAL
| others => RATIONAL
| DISCRETE_CHOICE_LIST => RATIONAL
RATIONAL ::= [-] NUMERIC_LITERAL [/ NUMERIC_LITERAL]
This aspect can only be applied to a subtype whose parent type has
a `Dimension_Systen` aspect. The aspect must specify values for
all dimensions of the system. The rational values are the powers of the
corresponding dimensions that are used by the compiler to verify that
physical (numeric) computations are dimensionally consistent. For example,
the computation of a force must result in dimensions (L => 1, M => 1, T => -2).
For further examples of the usage
of this aspect, see package `System.Dim.Mks`.
Note that when the dimensioned type is an integer type, then any
dimension value must be an integer literal.
Aspect Dimension_System
=======================
.. index:: Dimension_System
The `Dimension_System` aspect is used to define a system of
dimensions that will be used in subsequent subtype declarations with
`Dimension` aspects that reference this system. The syntax is::
with Dimension_System => (DIMENSION {, DIMENSION});
DIMENSION ::= ([Unit_Name =>] IDENTIFIER,
[Unit_Symbol =>] SYMBOL,
[Dim_Symbol =>] SYMBOL)
SYMBOL ::= CHARACTER_LITERAL | STRING_LITERAL
This aspect is applied to a type, which must be a numeric derived type
(typically a floating-point type), that
will represent values within the dimension system. Each `DIMENSION`
corresponds to one particular dimension. A maximum of 7 dimensions may
be specified. `Unit_Name` is the name of the dimension (for example
`Meter`). `Unit_Symbol` is the shorthand used for quantities
of this dimension (for example `m` for `Meter`).
`Dim_Symbol` gives
the identification within the dimension system (typically this is a
single letter, e.g. `L` standing for length for unit name `Meter`).
The `Unit_Symbol` is used in formatted output of dimensioned quantities.
The `Dim_Symbol` is used in error messages when numeric operations have
inconsistent dimensions.
GNAT provides the standard definition of the International MKS system in
the run-time package `System.Dim.Mks`. You can easily define
similar packages for cgs units or British units, and define conversion factors
between values in different systems. The MKS system is characterized by the
following aspect:
.. code-block:: ada
type Mks_Type is new Long_Long_Float with
Dimension_System => (
(Unit_Name => Meter, Unit_Symbol => 'm', Dim_Symbol => 'L'),
(Unit_Name => Kilogram, Unit_Symbol => "kg", Dim_Symbol => 'M'),
(Unit_Name => Second, Unit_Symbol => 's', Dim_Symbol => 'T'),
(Unit_Name => Ampere, Unit_Symbol => 'A', Dim_Symbol => 'I'),
(Unit_Name => Kelvin, Unit_Symbol => 'K', Dim_Symbol => '@'),
(Unit_Name => Mole, Unit_Symbol => "mol", Dim_Symbol => 'N'),
(Unit_Name => Candela, Unit_Symbol => "cd", Dim_Symbol => 'J'));
Note that in the above type definition, we use the `at` symbol (``@``) to
represent a theta character (avoiding the use of extended Latin-1
characters in this context).
See section 'Performing Dimensionality Analysis in GNAT' in the GNAT Users
Guide for detailed examples of use of the dimension system.
Aspect Effective_Reads
======================
.. index:: Effective_Reads
This aspect is equivalent to pragma `Effective_Reads`.
Aspect Effective_Writes
=======================
.. index:: Effective_Writes
This aspect is equivalent to pragma `Effective_Writes`.
Aspect Favor_Top_Level
======================
.. index:: Favor_Top_Level
This boolean aspect is equivalent to pragma `Favor_Top_Level`.
Aspect Global
=============
.. index:: Global
This aspect is equivalent to pragma `Global`.
Aspect Initial_Condition
========================
.. index:: Initial_Condition
This aspect is equivalent to pragma `Initial_Condition`.
Aspect Initializes
==================
.. index:: Initializes
This aspect is equivalent to pragma `Initializes`.
Aspect Inline_Always
====================
.. index:: Inline_Always
This boolean aspect is equivalent to pragma `Inline_Always`.
Aspect Invariant
================
.. index:: Invariant
This aspect is equivalent to pragma `Invariant`. It is a
synonym for the language defined aspect `Type_Invariant` except
that it is separately controllable using pragma `Assertion_Policy`.
Aspect Invariant'Class
======================
.. index:: Invariant'Class
This aspect is equivalent to pragma `Type_Invariant_Class`. It is a
synonym for the language defined aspect `Type_Invariant'Class` except
that it is separately controllable using pragma `Assertion_Policy`.
Aspect Iterable
===============
.. index:: Iterable
This aspect provides a light-weight mechanism for loops and quantified
expressions over container types, without the overhead imposed by the tampering
checks of standard Ada 2012 iterators. The value of the aspect is an aggregate
with four named components: `First`, `Next`, `Has_Element`, and `Element` (the
last one being optional). When only 3 components are specified, only the
`for .. in` form of iteration over cursors is available. When all 4 components
are specified, both this form and the `for .. of` form of iteration over
elements are available. The following is a typical example of use:
.. code-block:: ada
type List is private with
Iterable => (First => First_Cursor,
Next => Advance,
Has_Element => Cursor_Has_Element,
[Element => Get_Element]);
* The value denoted by `First` must denote a primitive operation of the
container type that returns a `Cursor`, which must a be a type declared in
the container package or visible from it. For example:
.. code-block:: ada
function First_Cursor (Cont : Container) return Cursor;
* The value of `Next` is a primitive operation of the container type that takes
both a container and a cursor and yields a cursor. For example:
.. code-block:: ada
function Advance (Cont : Container; Position : Cursor) return Cursor;
* The value of `Has_Element` is a primitive operation of the container type
that takes both a container and a cursor and yields a boolean. For example:
.. code-block:: ada
function Cursor_Has_Element (Cont : Container; Position : Cursor) return Boolean;
* The value of `Element` is a primitive operation of the container type that
takes both a container and a cursor and yields an `Element_Type`, which must
be a type declared in the container package or visible from it. For example:
.. code-block:: ada
function Get_Element (Cont : Container; Position : Cursor) return Element_Type;
This aspect is used in the GNAT-defined formal container packages.
Aspect Linker_Section
=====================
.. index:: Linker_Section
This aspect is equivalent to an `Linker_Section` pragma.
Aspect Lock_Free
================
.. index:: Lock_Free
This boolean aspect is equivalent to pragma `Lock_Free`.
Aspect No_Elaboration_Code_All
==============================
.. index:: No_Elaboration_Code_All
This aspect is equivalent to a `pragma No_Elaboration_Code_All`
statement for a program unit.
Aspect No_Tagged_Streams
========================
.. index:: No_Tagged_Streams
This aspect is equivalent to a `pragma No_Tagged_Streams` with an
argument specifying a root tagged type (thus this aspect can only be
applied to such a type).
Aspect Object_Size
==================
.. index:: Object_Size
This aspect is equivalent to an `Object_Size` attribute definition
clause.
Aspect Obsolescent
==================
.. index:: Obsolsecent
This aspect is equivalent to an `Obsolescent` pragma. Note that the
evaluation of this aspect happens at the point of occurrence, it is not
delayed until the freeze point.
Aspect Part_Of
==============
.. index:: Part_Of
This aspect is equivalent to pragma `Part_Of`.
Aspect Persistent_BSS
=====================
.. index:: Persistent_BSS
This boolean aspect is equivalent to pragma `Persistent_BSS`.
Aspect Predicate
================
.. index:: Predicate
This aspect is equivalent to pragma `Predicate`. It is thus
similar to the language defined aspects `Dynamic_Predicate`
and `Static_Predicate` except that whether the resulting
predicate is static or dynamic is controlled by the form of the
expression. It is also separately controllable using pragma
`Assertion_Policy`.
Aspect Pure_Function
====================
.. index:: Pure_Function
This boolean aspect is equivalent to pragma `Pure_Function`.
Aspect Refined_Depends
======================
.. index:: Refined_Depends
This aspect is equivalent to pragma `Refined_Depends`.
Aspect Refined_Global
=====================
.. index:: Refined_Global
This aspect is equivalent to pragma `Refined_Global`.
Aspect Refined_Post
===================
.. index:: Refined_Post
This aspect is equivalent to pragma `Refined_Post`.
Aspect Refined_State
====================
.. index:: Refined_State
This aspect is equivalent to pragma `Refined_State`.
Aspect Remote_Access_Type
=========================
.. index:: Remote_Access_Type
This aspect is equivalent to pragma `Remote_Access_Type`.
Aspect Scalar_Storage_Order
===========================
.. index:: Scalar_Storage_Order
This aspect is equivalent to a `Scalar_Storage_Order`
attribute definition clause.
Aspect Shared
=============
.. index:: Shared
This boolean aspect is equivalent to pragma `Shared`,
and is thus a synonym for aspect `Atomic`.
Aspect Simple_Storage_Pool
==========================
.. index:: Simple_Storage_Pool
This aspect is equivalent to a `Simple_Storage_Pool`
attribute definition clause.
Aspect Simple_Storage_Pool_Type
===============================
.. index:: Simple_Storage_Pool_Type
This boolean aspect is equivalent to pragma `Simple_Storage_Pool_Type`.
Aspect SPARK_Mode
=================
.. index:: SPARK_Mode
This aspect is equivalent to pragma `SPARK_Mode` and
may be specified for either or both of the specification and body
of a subprogram or package.
Aspect Suppress_Debug_Info
==========================
.. index:: Suppress_Debug_Info
This boolean aspect is equivalent to pragma `Suppress_Debug_Info`.
Aspect Suppress_Initialization
==============================
.. index:: Suppress_Initialization
This boolean aspect is equivalent to pragma `Suppress_Initialization`.
Aspect Test_Case
================
.. index:: Test_Case
This aspect is equivalent to pragma `Test_Case`.
Aspect Thread_Local_Storage
===========================
.. index:: Thread_Local_Storage
This boolean aspect is equivalent to pragma `Thread_Local_Storage`.
Aspect Universal_Aliasing
=========================
.. index:: Universal_Aliasing
This boolean aspect is equivalent to pragma `Universal_Aliasing`.
Aspect Universal_Data
=====================
.. index:: Universal_Data
This aspect is equivalent to pragma `Universal_Data`.
Aspect Unmodified
=================
.. index:: Unmodified
This boolean aspect is equivalent to pragma `Unmodified`.
Aspect Unreferenced
===================
.. index:: Unreferenced
This boolean aspect is equivalent to pragma `Unreferenced`. Note that
in the case of formal parameters, it is not permitted to have aspects for
a formal parameter, so in this case the pragma form must be used.
Aspect Unreferenced_Objects
===========================
.. index:: Unreferenced_Objects
This boolean aspect is equivalent to pragma `Unreferenced_Objects`.
Aspect Value_Size
=================
.. index:: Value_Size
This aspect is equivalent to a `Value_Size`
attribute definition clause.
Aspect Warnings
===============
.. index:: Warnings
This aspect is equivalent to the two argument form of pragma `Warnings`,
where the first argument is `ON` or `OFF` and the second argument
is the entity.
.. _Implementation_Defined_Attributes:
*********************************
Implementation Defined Attributes
*********************************
Ada defines (throughout the Ada reference manual,
summarized in Annex K),
a set of attributes that provide useful additional functionality in all
areas of the language. These language defined attributes are implemented
in GNAT and work as described in the Ada Reference Manual.
In addition, Ada allows implementations to define additional
attributes whose meaning is defined by the implementation. GNAT provides
a number of these implementation-dependent attributes which can be used
to extend and enhance the functionality of the compiler. This section of
the GNAT reference manual describes these additional attributes. It also
describes additional implementation-dependent features of standard
language-defined attributes.
Note that any program using these attributes may not be portable to
other compilers (although GNAT implements this set of attributes on all
platforms). Therefore if portability to other compilers is an important
consideration, you should minimize the use of these attributes.
Attribute Abort_Signal
======================
.. index:: Abort_Signal
`Standard'Abort_Signal` (`Standard` is the only allowed
prefix) provides the entity for the special exception used to signal
task abort or asynchronous transfer of control. Normally this attribute
should only be used in the tasking runtime (it is highly peculiar, and
completely outside the normal semantics of Ada, for a user program to
intercept the abort exception).
Attribute Address_Size
======================
.. index:: Size of `Address`
.. index:: Address_Size
`Standard'Address_Size` (`Standard` is the only allowed
prefix) is a static constant giving the number of bits in an
`Address`. It is the same value as System.Address'Size,
but has the advantage of being static, while a direct
reference to System.Address'Size is non-static because Address
is a private type.
Attribute Asm_Input
===================
.. index:: Asm_Input
The `Asm_Input` attribute denotes a function that takes two
parameters. The first is a string, the second is an expression of the
type designated by the prefix. The first (string) argument is required
to be a static expression, and is the constraint for the parameter,
(e.g., what kind of register is required). The second argument is the
value to be used as the input argument. The possible values for the
constant are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
:ref:`Machine_Code_Insertions`
Attribute Asm_Output
====================
.. index:: Asm_Output
The `Asm_Output` attribute denotes a function that takes two
parameters. The first is a string, the second is the name of a variable
of the type designated by the attribute prefix. The first (string)
argument is required to be a static expression and designates the
constraint for the parameter (e.g., what kind of register is
required). The second argument is the variable to be updated with the
result. The possible values for constraint are the same as those used in
the RTL, and are dependent on the configuration file used to build the
GCC back end. If there are no output operands, then this argument may
either be omitted, or explicitly given as `No_Output_Operands`.
:ref:`Machine_Code_Insertions`
Attribute Atomic_Always_Lock_Free
=================================
.. index:: Atomic_Always_Lock_Free
The prefix of the `Atomic_Always_Lock_Free` attribute is a type.
The result is a Boolean value which is True if the type has discriminants,
and False otherwise. The result indicate whether atomic operations are
supported by the target for the given type.
Attribute Bit
=============
.. index:: Bit
``obj'Bit``, where `obj` is any object, yields the bit
offset within the storage unit (byte) that contains the first bit of
storage allocated for the object. The value of this attribute is of the
type `Universal_Integer`, and is always a non-negative number not
exceeding the value of `System.Storage_Unit`.
For an object that is a variable or a constant allocated in a register,
the value is zero. (The use of this attribute does not force the
allocation of a variable to memory).
For an object that is a formal parameter, this attribute applies
to either the matching actual parameter or to a copy of the
matching actual parameter.
For an access object the value is zero. Note that
``obj.all'Bit`` is subject to an `Access_Check` for the
designated object. Similarly for a record component
``X.C'Bit`` is subject to a discriminant check and
``X(I).Bit`` and ``X(I1..I2)'Bit``
are subject to index checks.
This attribute is designed to be compatible with the DEC Ada 83 definition
and implementation of the `Bit` attribute.
Attribute Bit_Position
======================
.. index:: Bit_Position
``R.C'Bit_Position``, where `R` is a record object and `C` is one
of the fields of the record type, yields the bit
offset within the record contains the first bit of
storage allocated for the object. The value of this attribute is of the
type `Universal_Integer`. The value depends only on the field
`C` and is independent of the alignment of
the containing record `R`.
Attribute Code_Address
======================
.. index:: Code_Address
.. index:: Subprogram address
.. index:: Address of subprogram code
The `'Address`
attribute may be applied to subprograms in Ada 95 and Ada 2005, but the
intended effect seems to be to provide
an address value which can be used to call the subprogram by means of
an address clause as in the following example:
.. code-block:: ada
procedure K is ...
procedure L;
for L'Address use K'Address;
pragma Import (Ada, L);
A call to `L` is then expected to result in a call to `K`.
In Ada 83, where there were no access-to-subprogram values, this was
a common work-around for getting the effect of an indirect call.
GNAT implements the above use of `Address` and the technique
illustrated by the example code works correctly.
However, for some purposes, it is useful to have the address of the start
of the generated code for the subprogram. On some architectures, this is
not necessarily the same as the `Address` value described above.
For example, the `Address` value may reference a subprogram
descriptor rather than the subprogram itself.
The `'Code_Address` attribute, which can only be applied to
subprogram entities, always returns the address of the start of the
generated code of the specified subprogram, which may or may not be
the same value as is returned by the corresponding `'Address`
attribute.
Attribute Compiler_Version
==========================
.. index:: Compiler_Version
`Standard'Compiler_Version` (`Standard` is the only allowed
prefix) yields a static string identifying the version of the compiler
being used to compile the unit containing the attribute reference.
Attribute Constrained
=====================
.. index:: Constrained
In addition to the usage of this attribute in the Ada RM, `GNAT`
also permits the use of the `'Constrained` attribute
in a generic template
for any type, including types without discriminants. The value of this
attribute in the generic instance when applied to a scalar type or a
record type without discriminants is always `True`. This usage is
compatible with older Ada compilers, including notably DEC Ada.
Attribute Default_Bit_Order
===========================
.. index:: Big endian
.. index:: Little endian
.. index:: Default_Bit_Order
`Standard'Default_Bit_Order` (`Standard` is the only
permissible prefix), provides the value `System.Default_Bit_Order`
as a `Pos` value (0 for `High_Order_First`, 1 for
`Low_Order_First`). This is used to construct the definition of
`Default_Bit_Order` in package `System`.
Attribute Default_Scalar_Storage_Order
======================================
.. index:: Big endian
.. index:: Little endian
.. index:: Default_Scalar_Storage_Order
`Standard'Default_Scalar_Storage_Order` (`Standard` is the only
permissible prefix), provides the current value of the default scalar storage
order (as specified using pragma `Default_Scalar_Storage_Order`, or
equal to `Default_Bit_Order` if unspecified) as a
`System.Bit_Order` value. This is a static attribute.
Attribute Descriptor_Size
=========================
.. index:: Descriptor
.. index:: Dope vector
.. index:: Descriptor_Size
Non-static attribute `Descriptor_Size` returns the size in bits of the
descriptor allocated for a type. The result is non-zero only for unconstrained
array types and the returned value is of type universal integer. In GNAT, an
array descriptor contains bounds information and is located immediately before
the first element of the array.
.. code-block:: ada
type Unconstr_Array is array (Positive range <>) of Boolean;
Put_Line ("Descriptor size = " & Unconstr_Array'Descriptor_Size'Img);
The attribute takes into account any additional padding due to type alignment.
In the example above, the descriptor contains two values of type
`Positive` representing the low and high bound. Since `Positive` has
a size of 31 bits and an alignment of 4, the descriptor size is `2 * Positive'Size + 2` or 64 bits.
Attribute Elaborated
====================
.. index:: Elaborated
The prefix of the `'Elaborated` attribute must be a unit name. The
value is a Boolean which indicates whether or not the given unit has been
elaborated. This attribute is primarily intended for internal use by the
generated code for dynamic elaboration checking, but it can also be used
in user programs. The value will always be True once elaboration of all
units has been completed. An exception is for units which need no
elaboration, the value is always False for such units.
Attribute Elab_Body
===================
.. index:: Elab_Body
This attribute can only be applied to a program unit name. It returns
the entity for the corresponding elaboration procedure for elaborating
the body of the referenced unit. This is used in the main generated
elaboration procedure by the binder and is not normally used in any
other context. However, there may be specialized situations in which it
is useful to be able to call this elaboration procedure from Ada code,
e.g., if it is necessary to do selective re-elaboration to fix some
error.
Attribute Elab_Spec
===================
.. index:: Elab_Spec
This attribute can only be applied to a program unit name. It returns
the entity for the corresponding elaboration procedure for elaborating
the spec of the referenced unit. This is used in the main
generated elaboration procedure by the binder and is not normally used
in any other context. However, there may be specialized situations in
which it is useful to be able to call this elaboration procedure from
Ada code, e.g., if it is necessary to do selective re-elaboration to fix
some error.
Attribute Elab_Subp_Body
========================
.. index:: Elab_Subp_Body
This attribute can only be applied to a library level subprogram
name and is only allowed in CodePeer mode. It returns the entity
for the corresponding elaboration procedure for elaborating the body
of the referenced subprogram unit. This is used in the main generated
elaboration procedure by the binder in CodePeer mode only and is unrecognized
otherwise.
Attribute Emax
==============
.. index:: Ada 83 attributes
.. index:: Emax
The `Emax` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Enabled
=================
.. index:: Enabled
The `Enabled` attribute allows an application program to check at compile
time to see if the designated check is currently enabled. The prefix is a
simple identifier, referencing any predefined check name (other than
`All_Checks`) or a check name introduced by pragma Check_Name. If
no argument is given for the attribute, the check is for the general state
of the check, if an argument is given, then it is an entity name, and the
check indicates whether an `Suppress` or `Unsuppress` has been
given naming the entity (if not, then the argument is ignored).
Note that instantiations inherit the check status at the point of the
instantiation, so a useful idiom is to have a library package that
introduces a check name with `pragma Check_Name`, and then contains
generic packages or subprograms which use the `Enabled` attribute
to see if the check is enabled. A user of this package can then issue
a `pragma Suppress` or `pragma Unsuppress` before instantiating
the package or subprogram, controlling whether the check will be present.
Attribute Enum_Rep
==================
.. index:: Representation of enums
.. index:: Enum_Rep
For every enumeration subtype `S`, ``S'Enum_Rep`` denotes a
function with the following spec:
.. code-block:: ada
function S'Enum_Rep (Arg : S'Base) return <Universal_Integer>;
It is also allowable to apply `Enum_Rep` directly to an object of an
enumeration type or to a non-overloaded enumeration
literal. In this case ``S'Enum_Rep`` is equivalent to
``typ'Enum_Rep(S)`` where `typ` is the type of the
enumeration literal or object.
The function returns the representation value for the given enumeration
value. This will be equal to value of the `Pos` attribute in the
absence of an enumeration representation clause. This is a static
attribute (i.e.,:the result is static if the argument is static).
``S'Enum_Rep`` can also be used with integer types and objects,
in which case it simply returns the integer value. The reason for this
is to allow it to be used for `(<>)` discrete formal arguments in
a generic unit that can be instantiated with either enumeration types
or integer types. Note that if `Enum_Rep` is used on a modular
type whose upper bound exceeds the upper bound of the largest signed
integer type, and the argument is a variable, so that the universal
integer calculation is done at run time, then the call to `Enum_Rep`
may raise `Constraint_Error`.
Attribute Enum_Val
==================
.. index:: Representation of enums
.. index:: Enum_Val
For every enumeration subtype `S`, ``S'Enum_Val`` denotes a
function with the following spec:
.. code-block:: ada
function S'Enum_Val (Arg : <Universal_Integer>) return S'Base;
The function returns the enumeration value whose representation matches the
argument, or raises Constraint_Error if no enumeration literal of the type
has the matching value.
This will be equal to value of the `Val` attribute in the
absence of an enumeration representation clause. This is a static
attribute (i.e., the result is static if the argument is static).
Attribute Epsilon
=================
.. index:: Ada 83 attributes
.. index:: Epsilon
The `Epsilon` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Fast_Math
===================
.. index:: Fast_Math
`Standard'Fast_Math` (`Standard` is the only allowed
prefix) yields a static Boolean value that is True if pragma
`Fast_Math` is active, and False otherwise.
Attribute Fixed_Value
=====================
.. index:: Fixed_Value
For every fixed-point type `S`, ``S'Fixed_Value`` denotes a
function with the following specification:
.. code-block:: ada
function S'Fixed_Value (Arg : <Universal_Integer>) return S;
The value returned is the fixed-point value `V` such that::
V = Arg * S'Small
The effect is thus similar to first converting the argument to the
integer type used to represent `S`, and then doing an unchecked
conversion to the fixed-point type. The difference is
that there are full range checks, to ensure that the result is in range.
This attribute is primarily intended for use in implementation of the
input-output functions for fixed-point values.
Attribute From_Any
==================
.. index:: From_Any
This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
Attribute Has_Access_Values
===========================
.. index:: Access values, testing for
.. index:: Has_Access_Values
The prefix of the `Has_Access_Values` attribute is a type. The result
is a Boolean value which is True if the is an access type, or is a composite
type with a component (at any nesting depth) that is an access type, and is
False otherwise.
The intended use of this attribute is in conjunction with generic
definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has access values.
Attribute Has_Discriminants
===========================
.. index:: Discriminants, testing for
.. index:: Has_Discriminants
The prefix of the `Has_Discriminants` attribute is a type. The result
is a Boolean value which is True if the type has discriminants, and False
otherwise. The intended use of this attribute is in conjunction with generic
definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has discriminants.
Attribute Img
=============
.. index:: Img
The `Img` attribute differs from `Image` in that it is applied
directly to an object, and yields the same result as
`Image` for the subtype of the object. This is convenient for
debugging:
.. code-block:: ada
Put_Line ("X = " & X'Img);
has the same meaning as the more verbose:
.. code-block:: ada
Put_Line ("X = " & T'Image (X));
where `T` is the (sub)type of the object `X`.
Note that technically, in analogy to `Image`,
`X'Img` returns a parameterless function
that returns the appropriate string when called. This means that
`X'Img` can be renamed as a function-returning-string, or used
in an instantiation as a function parameter.
Attribute Integer_Value
=======================
.. index:: Integer_Value
For every integer type `S`, ``S'Integer_Value`` denotes a
function with the following spec:
.. code-block:: ada
function S'Integer_Value (Arg : <Universal_Fixed>) return S;
The value returned is the integer value `V`, such that::
Arg = V * T'Small
where `T` is the type of `Arg`.
The effect is thus similar to first doing an unchecked conversion from
the fixed-point type to its corresponding implementation type, and then
converting the result to the target integer type. The difference is
that there are full range checks, to ensure that the result is in range.
This attribute is primarily intended for use in implementation of the
standard input-output functions for fixed-point values.
Attribute Invalid_Value
=======================
.. index:: Invalid_Value
For every scalar type S, S'Invalid_Value returns an undefined value of the
type. If possible this value is an invalid representation for the type. The
value returned is identical to the value used to initialize an otherwise
uninitialized value of the type if pragma Initialize_Scalars is used,
including the ability to modify the value with the binder -Sxx flag and
relevant environment variables at run time.
Attribute Iterable
==================
.. index:: Iterable
Equivalent to Aspect Iterable.
Attribute Large
===============
.. index:: Ada 83 attributes
.. index:: Large
The `Large` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Library_Level
=======================
.. index:: Library_Level
`P'Library_Level`, where P is an entity name,
returns a Boolean value which is True if the entity is declared
at the library level, and False otherwise. Note that within a
generic instantition, the name of the generic unit denotes the
instance, which means that this attribute can be used to test
if a generic is instantiated at the library level, as shown
in this example:
.. code-block:: ada
generic
...
package Gen is
pragma Compile_Time_Error
(not Gen'Library_Level,
"Gen can only be instantiated at library level");
...
end Gen;
Attribute Lock_Free
===================
.. index:: Lock_Free
`P'Lock_Free`, where P is a protected object, returns True if a
pragma `Lock_Free` applies to P.
Attribute Loop_Entry
====================
.. index:: Loop_Entry
Syntax::
X'Loop_Entry [(loop_name)]
The `Loop_Entry` attribute is used to refer to the value that an
expression had upon entry to a given loop in much the same way that the
`Old` attribute in a subprogram postcondition can be used to refer
to the value an expression had upon entry to the subprogram. The
relevant loop is either identified by the given loop name, or it is the
innermost enclosing loop when no loop name is given.
A `Loop_Entry` attribute can only occur within a
`Loop_Variant` or `Loop_Invariant` pragma. A common use of
`Loop_Entry` is to compare the current value of objects with their
initial value at loop entry, in a `Loop_Invariant` pragma.
The effect of using `X'Loop_Entry` is the same as declaring
a constant initialized with the initial value of `X` at loop
entry. This copy is not performed if the loop is not entered, or if the
corresponding pragmas are ignored or disabled.
Attribute Machine_Size
======================
.. index:: Machine_Size
This attribute is identical to the `Object_Size` attribute. It is
provided for compatibility with the DEC Ada 83 attribute of this name.
Attribute Mantissa
==================
.. index:: Ada 83 attributes
.. index:: Mantissa
The `Mantissa` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
.. _Attribute_Maximum_Alignment:
Attribute Maximum_Alignment
===========================
.. index:: Alignment, maximum
.. index:: Maximum_Alignment
`Standard'Maximum_Alignment` (`Standard` is the only
permissible prefix) provides the maximum useful alignment value for the
target. This is a static value that can be used to specify the alignment
for an object, guaranteeing that it is properly aligned in all
cases.
Attribute Mechanism_Code
========================
.. index:: Return values, passing mechanism
.. index:: Parameters, passing mechanism
.. index:: Mechanism_Code
``function'Mechanism_Code`` yields an integer code for the
mechanism used for the result of function, and
``subprogram'Mechanism_Code (n)`` yields the mechanism
used for formal parameter number `n` (a static integer value with 1
meaning the first parameter) of `subprogram`. The code returned is:
*1*
by copy (value)
*2*
by reference
Attribute Null_Parameter
========================
.. index:: Zero address, passing
.. index:: Null_Parameter
A reference ``T'Null_Parameter`` denotes an imaginary object of
type or subtype `T` allocated at machine address zero. The attribute
is allowed only as the default expression of a formal parameter, or as
an actual expression of a subprogram call. In either case, the
subprogram must be imported.
The identity of the object is represented by the address zero in the
argument list, independent of the passing mechanism (explicit or
default).
This capability is needed to specify that a zero address should be
passed for a record or other composite object passed by reference.
There is no way of indicating this without the `Null_Parameter`
attribute.
Attribute Object_Size
=====================
.. index:: Size, used for objects
.. index:: Object_Size
The size of an object is not necessarily the same as the size of the type
of an object. This is because by default object sizes are increased to be
a multiple of the alignment of the object. For example,
`Natural'Size` is
31, but by default objects of type `Natural` will have a size of 32 bits.
Similarly, a record containing an integer and a character:
.. code-block:: ada
type Rec is record
I : Integer;
C : Character;
end record;
will have a size of 40 (that is `Rec'Size` will be 40). The
alignment will be 4, because of the
integer field, and so the default size of record objects for this type
will be 64 (8 bytes).
If the alignment of the above record is specified to be 1, then the
object size will be 40 (5 bytes). This is true by default, and also
an object size of 40 can be explicitly specified in this case.
A consequence of this capability is that different object sizes can be
given to subtypes that would otherwise be considered in Ada to be
statically matching. But it makes no sense to consider such subtypes
as statically matching. Consequently, in `GNAT` we add a rule
to the static matching rules that requires object sizes to match.
Consider this example:
.. code-block:: ada
1. procedure BadAVConvert is
2. type R is new Integer;
3. subtype R1 is R range 1 .. 10;
4. subtype R2 is R range 1 .. 10;
5. for R1'Object_Size use 8;
6. for R2'Object_Size use 16;
7. type R1P is access all R1;
8. type R2P is access all R2;
9. R1PV : R1P := new R1'(4);
10. R2PV : R2P;
11. begin
12. R2PV := R2P (R1PV);
|
>>> target designated subtype not compatible with
type "R1" defined at line 3
13. end;
In the absence of lines 5 and 6,
types `R1` and `R2` statically match and
hence the conversion on line 12 is legal. But since lines 5 and 6
cause the object sizes to differ, `GNAT` considers that types
`R1` and `R2` are not statically matching, and line 12
generates the diagnostic shown above.
Similar additional checks are performed in other contexts requiring
statically matching subtypes.
Attribute Old
=============
.. index:: Old
In addition to the usage of `Old` defined in the Ada 2012 RM (usage
within `Post` aspect), GNAT also permits the use of this attribute
in implementation defined pragmas `Postcondition`,
`Contract_Cases` and `Test_Case`. Also usages of
`Old` which would be illegal according to the Ada 2012 RM
definition are allowed under control of
implementation defined pragma `Unevaluated_Use_Of_Old`.
Attribute Passed_By_Reference
=============================
.. index:: Parameters, when passed by reference
.. index:: Passed_By_Reference
``type'Passed_By_Reference`` for any subtype `type` returns
a value of type `Boolean` value that is `True` if the type is
normally passed by reference and `False` if the type is normally
passed by copy in calls. For scalar types, the result is always `False`
and is static. For non-scalar types, the result is non-static.
Attribute Pool_Address
======================
.. index:: Parameters, when passed by reference
.. index:: Pool_Address
``X'Pool_Address`` for any object `X` returns the address
of X within its storage pool. This is the same as
``X'Address``, except that for an unconstrained array whose
bounds are allocated just before the first component,
``X'Pool_Address`` returns the address of those bounds,
whereas ``X'Address`` returns the address of the first
component.
Here, we are interpreting 'storage pool' broadly to mean
``wherever the object is allocated``, which could be a
user-defined storage pool,
the global heap, on the stack, or in a static memory area.
For an object created by `new`, ``Ptr.all'Pool_Address`` is
what is passed to `Allocate` and returned from `Deallocate`.
Attribute Range_Length
======================
.. index:: Range_Length
``type'Range_Length`` for any discrete type `type` yields
the number of values represented by the subtype (zero for a null
range). The result is static for static subtypes. `Range_Length`
applied to the index subtype of a one dimensional array always gives the
same result as `Length` applied to the array itself.
Attribute Ref
=============
.. index:: Ref
Attribute Restriction_Set
=========================
.. index:: Restriction_Set
.. index:: Restrictions
This attribute allows compile time testing of restrictions that
are currently in effect. It is primarily intended for specializing
code in the run-time based on restrictions that are active (e.g.
don't need to save fpt registers if restriction No_Floating_Point
is known to be in effect), but can be used anywhere.
There are two forms:
.. code-block:: ada
System'Restriction_Set (partition_boolean_restriction_NAME)
System'Restriction_Set (No_Dependence => library_unit_NAME);
In the case of the first form, the only restriction names
allowed are parameterless restrictions that are checked
for consistency at bind time. For a complete list see the
subtype `System.Rident.Partition_Boolean_Restrictions`.
The result returned is True if the restriction is known to
be in effect, and False if the restriction is known not to
be in effect. An important guarantee is that the value of
a Restriction_Set attribute is known to be consistent throughout
all the code of a partition.
This is trivially achieved if the entire partition is compiled
with a consistent set of restriction pragmas. However, the
compilation model does not require this. It is possible to
compile one set of units with one set of pragmas, and another
set of units with another set of pragmas. It is even possible
to compile a spec with one set of pragmas, and then WITH the
same spec with a different set of pragmas. Inconsistencies
in the actual use of the restriction are checked at bind time.
In order to achieve the guarantee of consistency for the
Restriction_Set pragma, we consider that a use of the pragma
that yields False is equivalent to a violation of the
restriction.
So for example if you write
.. code-block:: ada
if System'Restriction_Set (No_Floating_Point) then
...
else
...
end if;
And the result is False, so that the else branch is executed,
you can assume that this restriction is not set for any unit
in the partition. This is checked by considering this use of
the restriction pragma to be a violation of the restriction
No_Floating_Point. This means that no other unit can attempt
to set this restriction (if some unit does attempt to set it,
the binder will refuse to bind the partition).
Technical note: The restriction name and the unit name are
intepreted entirely syntactically, as in the corresponding
Restrictions pragma, they are not analyzed semantically,
so they do not have a type.
Attribute Result
================
.. index:: Result
``function'Result`` can only be used with in a Postcondition pragma
for a function. The prefix must be the name of the corresponding function. This
is used to refer to the result of the function in the postcondition expression.
For a further discussion of the use of this attribute and examples of its use,
see the description of pragma Postcondition.
Attribute Safe_Emax
===================
.. index:: Ada 83 attributes
.. index:: Safe_Emax
The `Safe_Emax` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Safe_Large
====================
.. index:: Ada 83 attributes
.. index:: Safe_Large
The `Safe_Large` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Safe_Small
====================
.. index:: Ada 83 attributes
.. index:: Safe_Small
The `Safe_Small` attribute is provided for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.
Attribute Scalar_Storage_Order
==============================
.. index:: Endianness
.. index:: Scalar storage order
.. index:: Scalar_Storage_Order
For every array or record type `S`, the representation attribute
`Scalar_Storage_Order` denotes the order in which storage elements
that make up scalar components are ordered within S. The value given must
be a static expression of type System.Bit_Order. The following is an example
of the use of this feature:
.. code-block:: ada
-- Component type definitions
subtype Yr_Type is Natural range 0 .. 127;
subtype Mo_Type is Natural range 1 .. 12;
subtype Da_Type is Natural range 1 .. 31;
-- Record declaration
type Date is record
Years_Since_1980 : Yr_Type;
Month : Mo_Type;
Day_Of_Month : Da_Type;
end record;
-- Record representation clause
for Date use record
Years_Since_1980 at 0 range 0 .. 6;
Month at 0 range 7 .. 10;
Day_Of_Month at 0 range 11 .. 15;
end record;
-- Attribute definition clauses
for Date'Bit_Order use System.High_Order_First;
for Date'Scalar_Storage_Order use System.High_Order_First;
-- If Scalar_Storage_Order is specified, it must be consistent with
-- Bit_Order, so it's best to always define the latter explicitly if
-- the former is used.
Other properties are as for standard representation attribute `Bit_Order`,
as defined by Ada RM 13.5.3(4). The default is `System.Default_Bit_Order`.
For a record type `T`, if ``T'Scalar_Storage_Order`` is
specified explicitly, it shall be equal to ``T'Bit_Order``. Note:
this means that if a `Scalar_Storage_Order` attribute definition
clause is not confirming, then the type's `Bit_Order` shall be
specified explicitly and set to the same value.
Derived types inherit an explicitly set scalar storage order from their parent
types. This may be overridden for the derived type by giving an explicit scalar
storage order for the derived type. For a record extension, the derived type
must have the same scalar storage order as the parent type.
If a component of `T` is of a record or array type, then that type must
also have a `Scalar_Storage_Order` attribute definition clause.
A component of a record or array type that is a packed array, or that
does not start on a byte boundary, must have the same scalar storage order
as the enclosing record or array type.
No component of a type that has an explicit `Scalar_Storage_Order`
attribute definition may be aliased.
A confirming `Scalar_Storage_Order` attribute definition clause (i.e.
with a value equal to `System.Default_Bit_Order`) has no effect.
If the opposite storage order is specified, then whenever the value of
a scalar component of an object of type `S` is read, the storage
elements of the enclosing machine scalar are first reversed (before
retrieving the component value, possibly applying some shift and mask
operatings on the enclosing machine scalar), and the opposite operation
is done for writes.
In that case, the restrictions set forth in 13.5.1(10.3/2) for scalar components
are relaxed. Instead, the following rules apply:
* the underlying storage elements are those at positions
`(position + first_bit / storage_element_size) .. (position + (last_bit + storage_element_size - 1) / storage_element_size)`
* the sequence of underlying storage elements shall have
a size no greater than the largest machine scalar
* the enclosing machine scalar is defined as the smallest machine
scalar starting at a position no greater than
`position + first_bit / storage_element_size` and covering
storage elements at least up to `position + (last_bit + storage_element_size - 1) / storage_element_size`
* the position of the component is interpreted relative to that machine
scalar.
If no scalar storage order is specified for a type (either directly, or by
inheritance in the case of a derived type), then the default is normally
the native ordering of the target, but this default can be overridden using
pragma `Default_Scalar_Storage_Order`.
Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.
.. _Attribute_Simple_Storage_Pool:
Attribute Simple_Storage_Pool
=============================
.. index:: Storage pool, simple
.. index:: Simple storage pool
.. index:: Simple_Storage_Pool
For every nonformal, nonderived access-to-object type `Acc`, the
representation attribute `Simple_Storage_Pool` may be specified
via an attribute_definition_clause (or by specifying the equivalent aspect):
.. code-block:: ada
My_Pool : My_Simple_Storage_Pool_Type;
type Acc is access My_Data_Type;
for Acc'Simple_Storage_Pool use My_Pool;
The name given in an attribute_definition_clause for the
`Simple_Storage_Pool` attribute shall denote a variable of
a 'simple storage pool type' (see pragma `Simple_Storage_Pool_Type`).
The use of this attribute is only allowed for a prefix denoting a type
for which it has been specified. The type of the attribute is the type
of the variable specified as the simple storage pool of the access type,
and the attribute denotes that variable.
It is illegal to specify both `Storage_Pool` and `Simple_Storage_Pool`
for the same access type.
If the `Simple_Storage_Pool` attribute has been specified for an access
type, then applying the `Storage_Pool` attribute to the type is flagged
with a warning and its evaluation raises the exception `Program_Error`.
If the Simple_Storage_Pool attribute has been specified for an access
type `S`, then the evaluation of the attribute ``S'Storage_Size``
returns the result of calling ``Storage_Size (S'Simple_Storage_Pool)``,
which is intended to indicate the number of storage elements reserved for
the simple storage pool. If the Storage_Size function has not been defined
for the simple storage pool type, then this attribute returns zero.
If an access type `S` has a specified simple storage pool of type
`SSP`, then the evaluation of an allocator for that access type calls
the primitive `Allocate` procedure for type `SSP`, passing
``S'Simple_Storage_Pool`` as the pool parameter. The detailed
semantics of such allocators is the same as those defined for allocators
in section 13.11 of the :title:`Ada Reference Manual`, with the term
`simple storage pool` substituted for `storage pool`.
If an access type `S` has a specified simple storage pool of type
`SSP`, then a call to an instance of the `Ada.Unchecked_Deallocation`
for that access type invokes the primitive `Deallocate` procedure
for type `SSP`, passing ``S'Simple_Storage_Pool`` as the pool
parameter. The detailed semantics of such unchecked deallocations is the same
as defined in section 13.11.2 of the Ada Reference Manual, except that the
term 'simple storage pool' is substituted for 'storage pool'.
Attribute Small
===============
.. index:: Ada 83 attributes
.. index:: Small
The `Small` attribute is defined in Ada 95 (and Ada 2005) only for
fixed-point types.
GNAT also allows this attribute to be applied to floating-point types
for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute when applied to floating-point types.
Attribute Storage_Unit
======================
.. index:: Storage_Unit
`Standard'Storage_Unit` (`Standard` is the only permissible
prefix) provides the same value as `System.Storage_Unit`.
Attribute Stub_Type
===================
.. index:: Stub_Type
The GNAT implementation of remote access-to-classwide types is
organized as described in AARM section E.4 (20.t): a value of an RACW type
(designating a remote object) is represented as a normal access
value, pointing to a "stub" object which in turn contains the
necessary information to contact the designated remote object. A
call on any dispatching operation of such a stub object does the
remote call, if necessary, using the information in the stub object
to locate the target partition, etc.
For a prefix `T` that denotes a remote access-to-classwide type,
`T'Stub_Type` denotes the type of the corresponding stub objects.
By construction, the layout of `T'Stub_Type` is identical to that of
type `RACW_Stub_Type` declared in the internal implementation-defined
unit `System.Partition_Interface`. Use of this attribute will create
an implicit dependency on this unit.
Attribute System_Allocator_Alignment
====================================
.. index:: Alignment, allocator
.. index:: System_Allocator_Alignment
`Standard'System_Allocator_Alignment` (`Standard` is the only
permissible prefix) provides the observable guaranted to be honored by
the system allocator (malloc). This is a static value that can be used
in user storage pools based on malloc either to reject allocation
with alignment too large or to enable a realignment circuitry if the
alignment request is larger than this value.
Attribute Target_Name
=====================
.. index:: Target_Name
`Standard'Target_Name` (`Standard` is the only permissible
prefix) provides a static string value that identifies the target
for the current compilation. For GCC implementations, this is the
standard gcc target name without the terminating slash (for
example, GNAT 5.0 on windows yields "i586-pc-mingw32msv").
Attribute To_Address
====================
.. index:: To_Address
The `System'To_Address`
(`System` is the only permissible prefix)
denotes a function identical to
`System.Storage_Elements.To_Address` except that
it is a static attribute. This means that if its argument is
a static expression, then the result of the attribute is a
static expression. This means that such an expression can be
used in contexts (e.g., preelaborable packages) which require a
static expression and where the function call could not be used
(since the function call is always non-static, even if its
argument is static). The argument must be in the range
-(2**(m-1) .. 2**m-1, where m is the memory size
(typically 32 or 64). Negative values are intepreted in a
modular manner (e.g., -1 means the same as 16#FFFF_FFFF# on
a 32 bits machine).
Attribute To_Any
================
.. index:: To_Any
This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
Attribute Type_Class
====================
.. index:: Type_Class
``type'Type_Class`` for any type or subtype `type` yields
the value of the type class for the full type of `type`. If
`type` is a generic formal type, the value is the value for the
corresponding actual subtype. The value of this attribute is of type
``System.Aux_DEC.Type_Class``, which has the following definition:
.. code-block:: ada
type Type_Class is
(Type_Class_Enumeration,
Type_Class_Integer,
Type_Class_Fixed_Point,
Type_Class_Floating_Point,
Type_Class_Array,
Type_Class_Record,
Type_Class_Access,
Type_Class_Task,
Type_Class_Address);
Protected types yield the value `Type_Class_Task`, which thus
applies to all concurrent types. This attribute is designed to
be compatible with the DEC Ada 83 attribute of the same name.
Attribute Type_Key
==================
.. index:: Type_Key
The `Type_Key` attribute is applicable to a type or subtype and
yields a value of type Standard.String containing encoded information
about the type or subtype. This provides improved compatibility with
other implementations that support this attribute.
Attribute TypeCode
==================
.. index:: TypeCode
This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
Attribute UET_Address
=====================
.. index:: UET_Address
The `UET_Address` attribute can only be used for a prefix which
denotes a library package. It yields the address of the unit exception
table when zero cost exception handling is used. This attribute is
intended only for use within the GNAT implementation. See the unit
`Ada.Exceptions` in files :file:`a-except.ads` and :file:`a-except.adb`
for details on how this attribute is used in the implementation.
Attribute Unconstrained_Array
=============================
.. index:: Unconstrained_Array
The `Unconstrained_Array` attribute can be used with a prefix that
denotes any type or subtype. It is a static attribute that yields
`True` if the prefix designates an unconstrained array,
and `False` otherwise. In a generic instance, the result is
still static, and yields the result of applying this test to the
generic actual.
Attribute Universal_Literal_String
==================================
.. index:: Named numbers, representation of
.. index:: Universal_Literal_String
The prefix of `Universal_Literal_String` must be a named
number. The static result is the string consisting of the characters of
the number as defined in the original source. This allows the user
program to access the actual text of named numbers without intermediate
conversions and without the need to enclose the strings in quotes (which
would preclude their use as numbers).
For example, the following program prints the first 50 digits of pi:
.. code-block:: ada
with Text_IO; use Text_IO;
with Ada.Numerics;
procedure Pi is
begin
Put (Ada.Numerics.Pi'Universal_Literal_String);
end;
Attribute Unrestricted_Access
=============================
.. index:: Access, unrestricted
.. index:: Unrestricted_Access
The `Unrestricted_Access` attribute is similar to `Access`
except that all accessibility and aliased view checks are omitted. This
is a user-beware attribute.
For objects, it is similar to `Address`, for which it is a
desirable replacement where the value desired is an access type.
In other words, its effect is similar to first applying the
`Address` attribute and then doing an unchecked conversion to a
desired access type.
For subprograms, `P'Unrestricted_Access` may be used where
`P'Access` would be illegal, to construct a value of a
less-nested named access type that designates a more-nested
subprogram. This value may be used in indirect calls, so long as the
more-nested subprogram still exists; once the subprogram containing it
has returned, such calls are erroneous. For example:
.. code-block:: ada
package body P is
type Less_Nested is not null access procedure;
Global : Less_Nested;
procedure P1 is
begin
Global.all;
end P1;
procedure P2 is
Local_Var : Integer;
procedure More_Nested is
begin
... Local_Var ...
end More_Nested;
begin
Global := More_Nested'Unrestricted_Access;
P1;
end P2;
end P;
When P1 is called from P2, the call via Global is OK, but if P1 were
called after P2 returns, it would be an erroneous use of a dangling
pointer.
For objects, it is possible to use `Unrestricted_Access` for any
type. However, if the result is of an access-to-unconstrained array
subtype, then the resulting pointer has the same scope as the context
of the attribute, and must not be returned to some enclosing scope.
For instance, if a function uses `Unrestricted_Access` to create
an access-to-unconstrained-array and returns that value to the caller,
the result will involve dangling pointers. In addition, it is only
valid to create pointers to unconstrained arrays using this attribute
if the pointer has the normal default 'fat' representation where a
pointer has two components, one points to the array and one points to
the bounds. If a size clause is used to force 'thin' representation
for a pointer to unconstrained where there is only space for a single
pointer, then the resulting pointer is not usable.
In the simple case where a direct use of Unrestricted_Access attempts
to make a thin pointer for a non-aliased object, the compiler will
reject the use as illegal, as shown in the following example:
.. code-block:: ada
with System; use System;
procedure SliceUA2 is
type A is access all String;
for A'Size use Standard'Address_Size;
procedure P (Arg : A) is
begin
null;
end P;
X : String := "hello world!";
X2 : aliased String := "hello world!";
AV : A := X'Unrestricted_Access; -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
begin
P (X'Unrestricted_Access); -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
P (X(7 .. 12)'Unrestricted_Access); -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
P (X2'Unrestricted_Access); -- OK
end;
but other cases cannot be detected by the compiler, and are
considered to be erroneous. Consider the following example:
.. code-block:: ada
with System; use System;
with System; use System;
procedure SliceUA is
type AF is access all String;
type A is access all String;
for A'Size use Standard'Address_Size;
procedure P (Arg : A) is
begin
if Arg'Length /= 6 then
raise Program_Error;
end if;
end P;
X : String := "hello world!";
Y : AF := X (7 .. 12)'Unrestricted_Access;
begin
P (A (Y));
end;
A normal unconstrained array value
or a constrained array object marked as aliased has the bounds in memory
just before the array, so a thin pointer can retrieve both the data and
the bounds. But in this case, the non-aliased object `X` does not have the
bounds before the string. If the size clause for type `A`
were not present, then the pointer
would be a fat pointer, where one component is a pointer to the bounds,
and all would be well. But with the size clause present, the conversion from
fat pointer to thin pointer in the call loses the bounds, and so this
is erroneous, and the program likely raises a `Program_Error` exception.
In general, it is advisable to completely
avoid mixing the use of thin pointers and the use of
`Unrestricted_Access` where the designated type is an
unconstrained array. The use of thin pointers should be restricted to
cases of porting legacy code that implicitly assumes the size of pointers,
and such code should not in any case be using this attribute.
Another erroneous situation arises if the attribute is
applied to a constant. The resulting pointer can be used to access the
constant, but the effect of trying to modify a constant in this manner
is not well-defined. Consider this example:
.. code-block:: ada
P : constant Integer := 4;
type R is access all Integer;
RV : R := P'Unrestricted_Access;
..
RV.all := 3;
Here we attempt to modify the constant P from 4 to 3, but the compiler may
or may not notice this attempt, and subsequent references to P may yield
either the value 3 or the value 4 or the assignment may blow up if the
compiler decides to put P in read-only memory. One particular case where
`Unrestricted_Access` can be used in this way is to modify the
value of an `IN` parameter:
.. code-block:: ada
procedure K (S : in String) is
type R is access all Character;
RV : R := S (3)'Unrestricted_Access;
begin
RV.all := 'a';
end;
In general this is a risky approach. It may appear to "work" but such uses of
`Unrestricted_Access` are potentially non-portable, even from one version
of `GNAT` to another, so are best avoided if possible.
Attribute Update
================
.. index:: Update
The `Update` attribute creates a copy of an array or record value
with one or more modified components. The syntax is::
PREFIX'Update ( RECORD_COMPONENT_ASSOCIATION_LIST )
PREFIX'Update ( ARRAY_COMPONENT_ASSOCIATION {, ARRAY_COMPONENT_ASSOCIATION } )
PREFIX'Update ( MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION
{, MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION } )
MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION ::= INDEX_EXPRESSION_LIST_LIST => EXPRESSION
INDEX_EXPRESSION_LIST_LIST ::= INDEX_EXPRESSION_LIST {| INDEX_EXPRESSION_LIST }
INDEX_EXPRESSION_LIST ::= ( EXPRESSION {, EXPRESSION } )
where `PREFIX` is the name of an array or record object, the
association list in parentheses does not contain an `others`
choice and the box symbol `<>` may not appear in any
expression. The effect is to yield a copy of the array or record value
which is unchanged apart from the components mentioned in the
association list, which are changed to the indicated value. The
original value of the array or record value is not affected. For
example:
.. code-block:: ada
type Arr is Array (1 .. 5) of Integer;
...
Avar1 : Arr := (1,2,3,4,5);
Avar2 : Arr := Avar1'Update (2 => 10, 3 .. 4 => 20);
yields a value for `Avar2` of 1,10,20,20,5 with `Avar1`
begin unmodified. Similarly:
.. code-block:: ada
type Rec is A, B, C : Integer;
...
Rvar1 : Rec := (A => 1, B => 2, C => 3);
Rvar2 : Rec := Rvar1'Update (B => 20);
yields a value for `Rvar2` of (A => 1, B => 20, C => 3),
with `Rvar1` being unmodifed.
Note that the value of the attribute reference is computed
completely before it is used. This means that if you write:
.. code-block:: ada
Avar1 := Avar1'Update (1 => 10, 2 => Function_Call);
then the value of `Avar1` is not modified if `Function_Call`
raises an exception, unlike the effect of a series of direct assignments
to elements of `Avar1`. In general this requires that
two extra complete copies of the object are required, which should be
kept in mind when considering efficiency.
The `Update` attribute cannot be applied to prefixes of a limited
type, and cannot reference discriminants in the case of a record type.
The accessibility level of an Update attribute result object is defined
as for an aggregate.
In the record case, no component can be mentioned more than once. In
the array case, two overlapping ranges can appear in the association list,
in which case the modifications are processed left to right.
Multi-dimensional arrays can be modified, as shown by this example:
.. code-block:: ada
A : array (1 .. 10, 1 .. 10) of Integer;
..
A := A'Update ((1, 2) => 20, (3, 4) => 30);
which changes element (1,2) to 20 and (3,4) to 30.
Attribute Valid_Scalars
=======================
.. index:: Valid_Scalars
The `'Valid_Scalars` attribute is intended to make it easier to
check the validity of scalar subcomponents of composite objects. It
is defined for any prefix `X` that denotes an object.
The value of this attribute is of the predefined type Boolean.
`X'Valid_Scalars` yields True if and only if evaluation of
`P'Valid` yields True for every scalar part P of X or if X has
no scalar parts. It is not specified in what order the scalar parts
are checked, nor whether any more are checked after any one of them
is determined to be invalid. If the prefix `X` is of a class-wide
type `T'Class` (where `T` is the associated specific type),
or if the prefix `X` is of a specific tagged type `T`, then
only the scalar parts of components of `T` are traversed; in other
words, components of extensions of `T` are not traversed even if
`T'Class (X)'Tag /= T'Tag` . The compiler will issue a warning if it can
be determined at compile time that the prefix of the attribute has no
scalar parts (e.g., if the prefix is of an access type, an interface type,
an undiscriminated task type, or an undiscriminated protected type).
For scalar types, `Valid_Scalars` is equivalent to `Valid`. The use
of this attribute is not permitted for `Unchecked_Union` types for which
in general it is not possible to determine the values of the discriminants.
Note: `Valid_Scalars` can generate a lot of code, especially in the case
of a large variant record. If the attribute is called in many places in the
same program applied to objects of the same type, it can reduce program size
to write a function with a single use of the attribute, and then call that
function from multiple places.
Attribute VADS_Size
===================
.. index:: Size, VADS compatibility
.. index:: VADS_Size
The `'VADS_Size` attribute is intended to make it easier to port
legacy code which relies on the semantics of `'Size` as implemented
by the VADS Ada 83 compiler. GNAT makes a best effort at duplicating the
same semantic interpretation. In particular, `'VADS_Size` applied
to a predefined or other primitive type with no Size clause yields the
Object_Size (for example, `Natural'Size` is 32 rather than 31 on
typical machines). In addition `'VADS_Size` applied to an object
gives the result that would be obtained by applying the attribute to
the corresponding type.
Attribute Value_Size
====================
.. index:: Size, setting for not-first subtype
.. index:: Value_Size
``type'Value_Size`` is the number of bits required to represent
a value of the given subtype. It is the same as ``type'Size``,
but, unlike `Size`, may be set for non-first subtypes.
Attribute Wchar_T_Size
======================
.. index:: Wchar_T_Size
`Standard'Wchar_T_Size` (`Standard` is the only permissible
prefix) provides the size in bits of the C `wchar_t` type
primarily for constructing the definition of this type in
package `Interfaces.C`. The result is a static constant.
Attribute Word_Size
===================
.. index:: Word_Size
`Standard'Word_Size` (`Standard` is the only permissible
prefix) provides the value `System.Word_Size`. The result is
a static constant.
.. _Implementation_Defined_Characteristics:
**************************************
Implementation Defined Characteristics
**************************************
In addition to the implementation dependent pragmas and attributes, and the
implementation advice, there are a number of other Ada features that are
potentially implementation dependent and are designated as
implementation-defined. These are mentioned throughout the Ada Reference
Manual, and are summarized in Annex M.
A requirement for conforming Ada compilers is that they provide
documentation describing how the implementation deals with each of these
issues. In this chapter you will find each point in Annex M listed,
followed by a description of how GNAT
handles the implementation dependence.
You can use this chapter as a guide to minimizing implementation
dependent features in your programs if portability to other compilers
and other operating systems is an important consideration. The numbers
in each entry below correspond to the paragraph numbers in the Ada
Reference Manual.
*
"Whether or not each recommendation given in Implementation
Advice is followed. See 1.1.2(37)."
See :ref:`Implementation_Advice`.
*
"Capacity limitations of the implementation. See 1.1.3(3)."
The complexity of programs that can be processed is limited only by the
total amount of available virtual memory, and disk space for the
generated object files.
*
"Variations from the standard that are impractical to avoid
given the implementation's execution environment. See 1.1.3(6)."
There are no variations from the standard.
*
"Which code_statements cause external
interactions. See 1.1.3(10)."
Any `code_statement` can potentially cause external interactions.
*
"The coded representation for the text of an Ada
program. See 2.1(4)."
See separate section on source representation.
*
"The control functions allowed in comments. See 2.1(14)."
See separate section on source representation.
*
"The representation for an end of line. See 2.2(2)."
See separate section on source representation.
*
"Maximum supported line length and lexical element
length. See 2.2(15)."
The maximum line length is 255 characters and the maximum length of
a lexical element is also 255 characters. This is the default setting
if not overridden by the use of compiler switch *-gnaty* (which
sets the maximum to 79) or *-gnatyMnn* which allows the maximum
line length to be specified to be any value up to 32767. The maximum
length of a lexical element is the same as the maximum line length.
*
"Implementation defined pragmas. See 2.8(14)."
See :ref:`Implementation_Defined_Pragmas`.
*
"Effect of pragma `Optimize`. See 2.8(27)."
Pragma `Optimize`, if given with a `Time` or `Space`
parameter, checks that the optimization flag is set, and aborts if it is
not.
*
"The sequence of characters of the value returned by
``S'Image`` when some of the graphic characters of
``S'Wide_Image`` are not defined in `Character`. See
3.5(37)."
The sequence of characters is as defined by the wide character encoding
method used for the source. See section on source representation for
further details.
*
"The predefined integer types declared in
`Standard`. See 3.5.4(25)."
====================== =======================================
Type Representation
====================== =======================================
*Short_Short_Integer* 8 bit signed
*Short_Integer* (Short) 16 bit signed
*Integer* 32 bit signed
*Long_Integer* 64 bit signed (on most 64 bit targets,
depending on the C definition of long).
32 bit signed (all other targets)
*Long_Long_Integer* 64 bit signed
====================== =======================================
*
"Any nonstandard integer types and the operators defined
for them. See 3.5.4(26)."
There are no nonstandard integer types.
*
"Any nonstandard real types and the operators defined for
them. See 3.5.6(8)."
There are no nonstandard real types.
*
"What combinations of requested decimal precision and range
are supported for floating point types. See 3.5.7(7)."
The precision and range is as defined by the IEEE standard.
*
"The predefined floating point types declared in
`Standard`. See 3.5.7(16)."
====================== ====================================================
Type Representation
====================== ====================================================
*Short_Float* 32 bit IEEE short
*Float* (Short) 32 bit IEEE short
*Long_Float* 64 bit IEEE long
*Long_Long_Float* 64 bit IEEE long (80 bit IEEE long on x86 processors)
====================== ====================================================
*
"The small of an ordinary fixed point type. See 3.5.9(8)."
`Fine_Delta` is 2**(-63)
*
"What combinations of small, range, and digits are
supported for fixed point types. See 3.5.9(10)."
Any combinations are permitted that do not result in a small less than
`Fine_Delta` and do not result in a mantissa larger than 63 bits.
If the mantissa is larger than 53 bits on machines where Long_Long_Float
is 64 bits (true of all architectures except ia32), then the output from
Text_IO is accurate to only 53 bits, rather than the full mantissa. This
is because floating-point conversions are used to convert fixed point.
*
"The result of `Tags.Expanded_Name` for types declared
within an unnamed `block_statement`. See 3.9(10)."
Block numbers of the form `B`nnn``, where `nnn` is a
decimal integer are allocated.
*
"Implementation-defined attributes. See 4.1.4(12)."
See :ref:`Implementation_Defined_Attributes`.
*
"Any implementation-defined time types. See 9.6(6)."
There are no implementation-defined time types.
*
"The time base associated with relative delays."
See 9.6(20). The time base used is that provided by the C library
function `gettimeofday`.
*
"The time base of the type `Calendar.Time`. See
9.6(23)."
The time base used is that provided by the C library function
`gettimeofday`.
*
"The time zone used for package `Calendar`
operations. See 9.6(24)."
The time zone used by package `Calendar` is the current system time zone
setting for local time, as accessed by the C library function
`localtime`.
*
"Any limit on `delay_until_statements` of
`select_statements`. See 9.6(29)."
There are no such limits.
*
"Whether or not two non-overlapping parts of a composite
object are independently addressable, in the case where packing, record
layout, or `Component_Size` is specified for the object. See
9.10(1)."
Separate components are independently addressable if they do not share
overlapping storage units.
*
"The representation for a compilation. See 10.1(2)."
A compilation is represented by a sequence of files presented to the
compiler in a single invocation of the *gcc* command.
*
"Any restrictions on compilations that contain multiple
compilation_units. See 10.1(4)."
No single file can contain more than one compilation unit, but any
sequence of files can be presented to the compiler as a single
compilation.
*
"The mechanisms for creating an environment and for adding
and replacing compilation units. See 10.1.4(3)."
See separate section on compilation model.
*
"The manner of explicitly assigning library units to a
partition. See 10.2(2)."
If a unit contains an Ada main program, then the Ada units for the partition
are determined by recursive application of the rules in the Ada Reference
Manual section 10.2(2-6). In other words, the Ada units will be those that
are needed by the main program, and then this definition of need is applied
recursively to those units, and the partition contains the transitive
closure determined by this relationship. In short, all the necessary units
are included, with no need to explicitly specify the list. If additional
units are required, e.g., by foreign language units, then all units must be
mentioned in the context clause of one of the needed Ada units.
If the partition contains no main program, or if the main program is in
a language other than Ada, then GNAT
provides the binder options *-z* and *-n* respectively, and in
this case a list of units can be explicitly supplied to the binder for
inclusion in the partition (all units needed by these units will also
be included automatically). For full details on the use of these
options, refer to the `GNAT Make Program gnatmake` in the
:title:`GNAT User's Guide`.
*
"The implementation-defined means, if any, of specifying
which compilation units are needed by a given compilation unit. See
10.2(2)."
The units needed by a given compilation unit are as defined in
the Ada Reference Manual section 10.2(2-6). There are no
implementation-defined pragmas or other implementation-defined
means for specifying needed units.
*
"The manner of designating the main subprogram of a
partition. See 10.2(7)."
The main program is designated by providing the name of the
corresponding :file:`ALI` file as the input parameter to the binder.
*
"The order of elaboration of `library_items`. See
10.2(18)."
The first constraint on ordering is that it meets the requirements of
Chapter 10 of the Ada Reference Manual. This still leaves some
implementation dependent choices, which are resolved by first
elaborating bodies as early as possible (i.e., in preference to specs
where there is a choice), and second by evaluating the immediate with
clauses of a unit to determine the probably best choice, and
third by elaborating in alphabetical order of unit names
where a choice still remains.
*
"Parameter passing and function return for the main
subprogram. See 10.2(21)."
The main program has no parameters. It may be a procedure, or a function
returning an integer type. In the latter case, the returned integer
value is the return code of the program (overriding any value that
may have been set by a call to `Ada.Command_Line.Set_Exit_Status`).
*
"The mechanisms for building and running partitions. See
10.2(24)."
GNAT itself supports programs with only a single partition. The GNATDIST
tool provided with the GLADE package (which also includes an implementation
of the PCS) provides a completely flexible method for building and running
programs consisting of multiple partitions. See the separate GLADE manual
for details.
*
"The details of program execution, including program
termination. See 10.2(25)."
See separate section on compilation model.
*
"The semantics of any non-active partitions supported by the
implementation. See 10.2(28)."
Passive partitions are supported on targets where shared memory is
provided by the operating system. See the GLADE reference manual for
further details.
*
"The information returned by `Exception_Message`. See
11.4.1(10)."
Exception message returns the null string unless a specific message has
been passed by the program.
*
"The result of `Exceptions.Exception_Name` for types
declared within an unnamed `block_statement`. See 11.4.1(12)."
Blocks have implementation defined names of the form `B`nnn``
where `nnn` is an integer.
*
"The information returned by
`Exception_Information`. See 11.4.1(13)."
`Exception_Information` returns a string in the following format::
*Exception_Name:* nnnnn
*Message:* mmmmm
*PID:* ppp
*Load address:* 0xhhhh
*Call stack traceback locations:*
0xhhhh 0xhhhh 0xhhhh ... 0xhhh
where
* `nnnn` is the fully qualified name of the exception in all upper
case letters. This line is always present.
* `mmmm` is the message (this line present only if message is non-null)
* `ppp` is the Process Id value as a decimal integer (this line is
present only if the Process Id is nonzero). Currently we are
not making use of this field.
* The Load address line, the Call stack traceback locations line and the
following values are present only if at least one traceback location was
recorded. The Load address indicates the address at which the main executable
was loaded; this line may not be present if operating system hasn't relocated
the main executable. The values are given in C style format, with lower case
letters for a-f, and only as many digits present as are necessary.
The line terminator sequence at the end of each line, including
the last line is a single `LF` character (`16#0A#`).
*
"Implementation-defined check names. See 11.5(27)."
The implementation defined check name Alignment_Check controls checking of
address clause values for proper alignment (that is, the address supplied
must be consistent with the alignment of the type).
The implementation defined check name Predicate_Check controls whether
predicate checks are generated.
The implementation defined check name Validity_Check controls whether
validity checks are generated.
In addition, a user program can add implementation-defined check names
by means of the pragma Check_Name.
*
"The interpretation of each aspect of representation. See
13.1(20)."
See separate section on data representations.
*
"Any restrictions placed upon representation items. See
13.1(20)."
See separate section on data representations.
*
"The meaning of `Size` for indefinite subtypes. See
13.3(48)."
Size for an indefinite subtype is the maximum possible size, except that
for the case of a subprogram parameter, the size of the parameter object
is the actual size.
*
"The default external representation for a type tag. See
13.3(75)."
The default external representation for a type tag is the fully expanded
name of the type in upper case letters.
*
"What determines whether a compilation unit is the same in
two different partitions. See 13.3(76)."
A compilation unit is the same in two different partitions if and only
if it derives from the same source file.
*
"Implementation-defined components. See 13.5.1(15)."
The only implementation defined component is the tag for a tagged type,
which contains a pointer to the dispatching table.
*
"If `Word_Size` = `Storage_Unit`, the default bit
ordering. See 13.5.3(5)."
`Word_Size` (32) is not the same as `Storage_Unit` (8) for this
implementation, so no non-default bit ordering is supported. The default
bit ordering corresponds to the natural endianness of the target architecture.
*
"The contents of the visible part of package `System`
and its language-defined children. See 13.7(2)."
See the definition of these packages in files :file:`system.ads` and
:file:`s-stoele.ads`. Note that two declarations are added to package
System.
.. code-block:: ada
Max_Priority : constant Positive := Priority'Last;
Max_Interrupt_Priority : constant Positive := Interrupt_Priority'Last;
*
"The contents of the visible part of package
`System.Machine_Code`, and the meaning of
`code_statements`. See 13.8(7)."
See the definition and documentation in file :file:`s-maccod.ads`.
*
"The effect of unchecked conversion. See 13.9(11)."
Unchecked conversion between types of the same size
results in an uninterpreted transmission of the bits from one type
to the other. If the types are of unequal sizes, then in the case of
discrete types, a shorter source is first zero or sign extended as
necessary, and a shorter target is simply truncated on the left.
For all non-discrete types, the source is first copied if necessary
to ensure that the alignment requirements of the target are met, then
a pointer is constructed to the source value, and the result is obtained
by dereferencing this pointer after converting it to be a pointer to the
target type. Unchecked conversions where the target subtype is an
unconstrained array are not permitted. If the target alignment is
greater than the source alignment, then a copy of the result is
made with appropriate alignment
*
"The semantics of operations on invalid representations.
See 13.9.2(10-11)."
For assignments and other operations where the use of invalid values cannot
result in erroneous behavior, the compiler ignores the possibility of invalid
values. An exception is raised at the point where an invalid value would
result in erroneous behavior. For example executing:
.. code-block:: ada
procedure invalidvals is
X : Integer := -1;
Y : Natural range 1 .. 10;
for Y'Address use X'Address;
Z : Natural range 1 .. 10;
A : array (Natural range 1 .. 10) of Integer;
begin
Z := Y; -- no exception
A (Z) := 3; -- exception raised;
end;
As indicated, an exception is raised on the array assignment, but not
on the simple assignment of the invalid negative value from Y to Z.
*
"The manner of choosing a storage pool for an access type
when `Storage_Pool` is not specified for the type. See 13.11(17)."
There are 3 different standard pools used by the compiler when
`Storage_Pool` is not specified depending whether the type is local
to a subprogram or defined at the library level and whether
`Storage_Size`is specified or not. See documentation in the runtime
library units `System.Pool_Global`, `System.Pool_Size` and
`System.Pool_Local` in files :file:`s-poosiz.ads`,
:file:`s-pooglo.ads` and :file:`s-pooloc.ads` for full details on the
default pools used.
*
"Whether or not the implementation provides user-accessible
names for the standard pool type(s). See 13.11(17)."
See documentation in the sources of the run time mentioned in the previous
paragraph. All these pools are accessible by means of `with`'ing
these units.
*
"The meaning of `Storage_Size`. See 13.11(18)."
`Storage_Size` is measured in storage units, and refers to the
total space available for an access type collection, or to the primary
stack space for a task.
*
"Implementation-defined aspects of storage pools. See
13.11(22)."
See documentation in the sources of the run time mentioned in the
paragraph about standard storage pools above
for details on GNAT-defined aspects of storage pools.
*
"The set of restrictions allowed in a pragma
`Restrictions`. See 13.12(7)."
See :ref:`Standard_and_Implementation_Defined_Restrictions`.
*
"The consequences of violating limitations on
`Restrictions` pragmas. See 13.12(9)."
Restrictions that can be checked at compile time result in illegalities
if violated. Currently there are no other consequences of violating
restrictions.
*
"The representation used by the `Read` and
`Write` attributes of elementary types in terms of stream
elements. See 13.13.2(9)."
The representation is the in-memory representation of the base type of
the type, using the number of bits corresponding to the
``type'Size`` value, and the natural ordering of the machine.
*
"The names and characteristics of the numeric subtypes
declared in the visible part of package `Standard`. See A.1(3)."
See items describing the integer and floating-point types supported.
*
"The string returned by `Character_Set_Version`.
See A.3.5(3)."
`Ada.Wide_Characters.Handling.Character_Set_Version` returns
the string "Unicode 4.0", referring to version 4.0 of the
Unicode specification.
*
"The accuracy actually achieved by the elementary
functions. See A.5.1(1)."
The elementary functions correspond to the functions available in the C
library. Only fast math mode is implemented.
*
"The sign of a zero result from some of the operators or
functions in `Numerics.Generic_Elementary_Functions`, when
`Float_Type'Signed_Zeros` is `True`. See A.5.1(46)."
The sign of zeroes follows the requirements of the IEEE 754 standard on
floating-point.
*
"The value of
`Numerics.Float_Random.Max_Image_Width`. See A.5.2(27)."
Maximum image width is 6864, see library file :file:`s-rannum.ads`.
*
"The value of
`Numerics.Discrete_Random.Max_Image_Width`. See A.5.2(27)."
Maximum image width is 6864, see library file :file:`s-rannum.ads`.
*
"The algorithms for random number generation. See
A.5.2(32)."
The algorithm is the Mersenne Twister, as documented in the source file
:file:`s-rannum.adb`. This version of the algorithm has a period of
2**19937-1.
*
"The string representation of a random number generator's
state. See A.5.2(38)."
The value returned by the Image function is the concatenation of
the fixed-width decimal representations of the 624 32-bit integers
of the state vector.
*
"The minimum time interval between calls to the
time-dependent Reset procedure that are guaranteed to initiate different
random number sequences. See A.5.2(45)."
The minimum period between reset calls to guarantee distinct series of
random numbers is one microsecond.
*
"The values of the `Model_Mantissa`,
`Model_Emin`, `Model_Epsilon`, `Model`,
`Safe_First`, and `Safe_Last` attributes, if the Numerics
Annex is not supported. See A.5.3(72)."
Run the compiler with *-gnatS* to produce a listing of package
`Standard`, has the values of all numeric attributes.
*
"Any implementation-defined characteristics of the
input-output packages. See A.7(14)."
There are no special implementation defined characteristics for these
packages.
*
"The value of `Buffer_Size` in `Storage_IO`. See
A.9(10)."
All type representations are contiguous, and the `Buffer_Size` is
the value of ``type'Size`` rounded up to the next storage unit
boundary.
*
"External files for standard input, standard output, and
standard error See A.10(5)."
These files are mapped onto the files provided by the C streams
libraries. See source file :file:`i-cstrea.ads` for further details.
*
"The accuracy of the value produced by `Put`. See
A.10.9(36)."
If more digits are requested in the output than are represented by the
precision of the value, zeroes are output in the corresponding least
significant digit positions.
*
"The meaning of `Argument_Count`, `Argument`, and
`Command_Name`. See A.15(1)."
These are mapped onto the `argv` and `argc` parameters of the
main program in the natural manner.
*
"The interpretation of the `Form` parameter in procedure
`Create_Directory`. See A.16(56)."
The `Form` parameter is not used.
*
"The interpretation of the `Form` parameter in procedure
`Create_Path`. See A.16(60)."
The `Form` parameter is not used.
*
"The interpretation of the `Form` parameter in procedure
`Copy_File`. See A.16(68)."
The `Form` parameter is case-insensitive.
Two fields are recognized in the `Form` parameter::
*preserve=<value>*
*mode=<value>*
<value> starts immediately after the character '=' and ends with the
character immediately preceding the next comma (',') or with the last
character of the parameter.
The only possible values for preserve= are:
================== ===================================================================
Value Meaning
================== ===================================================================
*no_attributes* Do not try to preserve any file attributes. This is the
default if no preserve= is found in Form.
*all_attributes* Try to preserve all file attributes (timestamps, access rights).
*timestamps* Preserve the timestamp of the copied file, but not the other
file attributes.
================== ===================================================================
The only possible values for mode= are:
============== ===============================================================================
Value Meaning
============== ===============================================================================
*copy* Only do the copy if the destination file does not already exist.
If it already exists, Copy_File fails.
*overwrite* Copy the file in all cases. Overwrite an already existing destination file.
*append* Append the original file to the destination file. If the destination file
does not exist, the destination file is a copy of the source file.
When mode=append, the field preserve=, if it exists, is not taken into account.
============== ===============================================================================
If the Form parameter includes one or both of the fields and the value or
values are incorrect, Copy_file fails with Use_Error.
Examples of correct Forms::
Form => "preserve=no_attributes,mode=overwrite" (the default)
Form => "mode=append"
Form => "mode=copy, preserve=all_attributes"
Examples of incorrect Forms::
Form => "preserve=junk"
Form => "mode=internal, preserve=timestamps"
*
"The interpretation of the `Pattern` parameter, when not the null string,
in the `Start_Search` and `Search` procedures.
See A.16(104) and A.16(112)."
When the `Pattern` parameter is not the null string, it is interpreted
according to the syntax of regular expressions as defined in the
`GNAT.Regexp` package.
See :ref:`GNAT.Regexp_(g-regexp.ads)`.
*
"Implementation-defined convention names. See B.1(11)."
The following convention names are supported
======================= ==============================================================================
Convention Name Interpretation
======================= ==============================================================================
*Ada* Ada
*Ada_Pass_By_Copy* Allowed for any types except by-reference types such as limited
records. Compatible with convention Ada, but causes any parameters
with this convention to be passed by copy.
*Ada_Pass_By_Reference* Allowed for any types except by-copy types such as scalars.
Compatible with convention Ada, but causes any parameters
with this convention to be passed by reference.
*Assembler* Assembly language
*Asm* Synonym for Assembler
*Assembly* Synonym for Assembler
*C* C
*C_Pass_By_Copy* Allowed only for record types, like C, but also notes that record
is to be passed by copy rather than reference.
*COBOL* COBOL
*C_Plus_Plus (or CPP)* C++
*Default* Treated the same as C
*External* Treated the same as C
*Fortran* Fortran
*Intrinsic* For support of pragma `Import` with convention Intrinsic, see
separate section on Intrinsic Subprograms.
*Stdcall* Stdcall (used for Windows implementations only). This convention correspond
to the WINAPI (previously called Pascal convention) C/C++ convention under
Windows. A routine with this convention cleans the stack before
exit. This pragma cannot be applied to a dispatching call.
*DLL* Synonym for Stdcall
*Win32* Synonym for Stdcall
*Stubbed* Stubbed is a special convention used to indicate that the body of the
subprogram will be entirely ignored. Any call to the subprogram
is converted into a raise of the `Program_Error` exception. If a
pragma `Import` specifies convention `stubbed` then no body need
be present at all. This convention is useful during development for the
inclusion of subprograms whose body has not yet been written.
In addition, all otherwise unrecognized convention names are also
treated as being synonymous with convention C. In all implementations
except for VMS, use of such other names results in a warning. In VMS
implementations, these names are accepted silently.
======================= ==============================================================================
*
"The meaning of link names. See B.1(36)."
Link names are the actual names used by the linker.
*
"The manner of choosing link names when neither the link
name nor the address of an imported or exported entity is specified. See
B.1(36)."
The default linker name is that which would be assigned by the relevant
external language, interpreting the Ada name as being in all lower case
letters.
*
"The effect of pragma `Linker_Options`. See B.1(37)."
The string passed to `Linker_Options` is presented uninterpreted as
an argument to the link command, unless it contains ASCII.NUL characters.
NUL characters if they appear act as argument separators, so for example
.. code-block:: ada
pragma Linker_Options ("-labc" & ASCII.NUL & "-ldef");
causes two separate arguments `-labc` and `-ldef` to be passed to the
linker. The order of linker options is preserved for a given unit. The final
list of options passed to the linker is in reverse order of the elaboration
order. For example, linker options for a body always appear before the options
from the corresponding package spec.
*
"The contents of the visible part of package
`Interfaces` and its language-defined descendants. See B.2(1)."
See files with prefix :file:`i-` in the distributed library.
*
"Implementation-defined children of package
`Interfaces`. The contents of the visible part of package
`Interfaces`. See B.2(11)."
See files with prefix :file:`i-` in the distributed library.
*
"The types `Floating`, `Long_Floating`,
`Binary`, `Long_Binary`, `Decimal_ Element`, and
`COBOL_Character`; and the initialization of the variables
`Ada_To_COBOL` and `COBOL_To_Ada`, in
`Interfaces.COBOL`. See B.4(50)."
===================== ====================================
COBOL Ada
===================== ====================================
*Floating* Float
*Long_Floating* (Floating) Long_Float
*Binary* Integer
*Long_Binary* Long_Long_Integer
*Decimal_Element* Character
*COBOL_Character* Character
===================== ====================================
For initialization, see the file :file:`i-cobol.ads` in the distributed library.
*
"Support for access to machine instructions. See C.1(1)."
See documentation in file :file:`s-maccod.ads` in the distributed library.
*
"Implementation-defined aspects of access to machine
operations. See C.1(9)."
See documentation in file :file:`s-maccod.ads` in the distributed library.
*
"Implementation-defined aspects of interrupts. See C.3(2)."
Interrupts are mapped to signals or conditions as appropriate. See
definition of unit
`Ada.Interrupt_Names` in source file :file:`a-intnam.ads` for details
on the interrupts supported on a particular target.
*
"Implementation-defined aspects of pre-elaboration. See
C.4(13)."
GNAT does not permit a partition to be restarted without reloading,
except under control of the debugger.
*
"The semantics of pragma `Discard_Names`. See C.5(7)."
Pragma `Discard_Names` causes names of enumeration literals to
be suppressed. In the presence of this pragma, the Image attribute
provides the image of the Pos of the literal, and Value accepts
Pos values.
*
"The result of the `Task_Identification.Image`
attribute. See C.7.1(7)."
The result of this attribute is a string that identifies
the object or component that denotes a given task. If a variable `Var`
has a task type, the image for this task will have the form `Var_`XXXXXXXX``,
where the suffix
is the hexadecimal representation of the virtual address of the corresponding
task control block. If the variable is an array of tasks, the image of each
task will have the form of an indexed component indicating the position of a
given task in the array, e.g., `Group(5)_`XXXXXXX``. If the task is a
component of a record, the image of the task will have the form of a selected
component. These rules are fully recursive, so that the image of a task that
is a subcomponent of a composite object corresponds to the expression that
designates this task.
If a task is created by an allocator, its image depends on the context. If the
allocator is part of an object declaration, the rules described above are used
to construct its image, and this image is not affected by subsequent
assignments. If the allocator appears within an expression, the image
includes only the name of the task type.
If the configuration pragma Discard_Names is present, or if the restriction
No_Implicit_Heap_Allocation is in effect, the image reduces to
the numeric suffix, that is to say the hexadecimal representation of the
virtual address of the control block of the task.
*
"The value of `Current_Task` when in a protected entry
or interrupt handler. See C.7.1(17)."
Protected entries or interrupt handlers can be executed by any
convenient thread, so the value of `Current_Task` is undefined.
*
"The effect of calling `Current_Task` from an entry
body or interrupt handler. See C.7.1(19)."
The effect of calling `Current_Task` from an entry body or
interrupt handler is to return the identification of the task currently
executing the code.
*
"Implementation-defined aspects of
`Task_Attributes`. See C.7.2(19)."
There are no implementation-defined aspects of `Task_Attributes`.
*
"Values of all `Metrics`. See D(2)."
The metrics information for GNAT depends on the performance of the
underlying operating system. The sources of the run-time for tasking
implementation, together with the output from *-gnatG* can be
used to determine the exact sequence of operating systems calls made
to implement various tasking constructs. Together with appropriate
information on the performance of the underlying operating system,
on the exact target in use, this information can be used to determine
the required metrics.
*
"The declarations of `Any_Priority` and
`Priority`. See D.1(11)."
See declarations in file :file:`system.ads`.
*
"Implementation-defined execution resources. See D.1(15)."
There are no implementation-defined execution resources.
*
"Whether, on a multiprocessor, a task that is waiting for
access to a protected object keeps its processor busy. See D.2.1(3)."
On a multi-processor, a task that is waiting for access to a protected
object does not keep its processor busy.
*
"The affect of implementation defined execution resources
on task dispatching. See D.2.1(9)."
Tasks map to threads in the threads package used by GNAT. Where possible
and appropriate, these threads correspond to native threads of the
underlying operating system.
*
"Implementation-defined `policy_identifiers` allowed
in a pragma `Task_Dispatching_Policy`. See D.2.2(3)."
There are no implementation-defined policy-identifiers allowed in this
pragma.
*
"Implementation-defined aspects of priority inversion. See
D.2.2(16)."
Execution of a task cannot be preempted by the implementation processing
of delay expirations for lower priority tasks.
*
"Implementation-defined task dispatching. See D.2.2(18)."
The policy is the same as that of the underlying threads implementation.
*
"Implementation-defined `policy_identifiers` allowed
in a pragma `Locking_Policy`. See D.3(4)."
The two implementation defined policies permitted in GNAT are
`Inheritance_Locking` and `Conccurent_Readers_Locking`. On
targets that support the `Inheritance_Locking` policy, locking is
implemented by inheritance, i.e., the task owning the lock operates
at a priority equal to the highest priority of any task currently
requesting the lock. On targets that support the
`Conccurent_Readers_Locking` policy, locking is implemented with a
read/write lock allowing multiple propected object functions to enter
concurrently.
*
"Default ceiling priorities. See D.3(10)."
The ceiling priority of protected objects of the type
`System.Interrupt_Priority'Last` as described in the Ada
Reference Manual D.3(10),
*
"The ceiling of any protected object used internally by
the implementation. See D.3(16)."
The ceiling priority of internal protected objects is
`System.Priority'Last`.
*
"Implementation-defined queuing policies. See D.4(1)."
There are no implementation-defined queuing policies.
*
"On a multiprocessor, any conditions that cause the
completion of an aborted construct to be delayed later than what is
specified for a single processor. See D.6(3)."
The semantics for abort on a multi-processor is the same as on a single
processor, there are no further delays.
*
"Any operations that implicitly require heap storage
allocation. See D.7(8)."
The only operation that implicitly requires heap storage allocation is
task creation.
*
"What happens when a task terminates in the presence of
pragma `No_Task_Termination`. See D.7(15)."
Execution is erroneous in that case.
*
"Implementation-defined aspects of pragma
`Restrictions`. See D.7(20)."
There are no such implementation-defined aspects.
*
"Implementation-defined aspects of package
`Real_Time`. See D.8(17)."
There are no implementation defined aspects of package `Real_Time`.
*
"Implementation-defined aspects of
`delay_statements`. See D.9(8)."
Any difference greater than one microsecond will cause the task to be
delayed (see D.9(7)).
*
"The upper bound on the duration of interrupt blocking
caused by the implementation. See D.12(5)."
The upper bound is determined by the underlying operating system. In
no cases is it more than 10 milliseconds.
*
"The means for creating and executing distributed
programs. See E(5)."
The GLADE package provides a utility GNATDIST for creating and executing
distributed programs. See the GLADE reference manual for further details.
*
"Any events that can result in a partition becoming
inaccessible. See E.1(7)."
See the GLADE reference manual for full details on such events.
*
"The scheduling policies, treatment of priorities, and
management of shared resources between partitions in certain cases. See
E.1(11)."
See the GLADE reference manual for full details on these aspects of
multi-partition execution.
*
"Events that cause the version of a compilation unit to
change. See E.3(5)."
Editing the source file of a compilation unit, or the source files of
any units on which it is dependent in a significant way cause the version
to change. No other actions cause the version number to change. All changes
are significant except those which affect only layout, capitalization or
comments.
*
"Whether the execution of the remote subprogram is
immediately aborted as a result of cancellation. See E.4(13)."
See the GLADE reference manual for details on the effect of abort in
a distributed application.
*
"Implementation-defined aspects of the PCS. See E.5(25)."
See the GLADE reference manual for a full description of all implementation
defined aspects of the PCS.
*
"Implementation-defined interfaces in the PCS. See
E.5(26)."
See the GLADE reference manual for a full description of all
implementation defined interfaces.
*
"The values of named numbers in the package
`Decimal`. See F.2(7)."
==================== ==========
Named Number Value
==================== ==========
*Max_Scale* +18
*Min_Scale* -18
*Min_Delta* 1.0E-18
*Max_Delta* 1.0E+18
*Max_Decimal_Digits* 18
==================== ==========
*
"The value of `Max_Picture_Length` in the package
`Text_IO.Editing`. See F.3.3(16)."
64
*
"The value of `Max_Picture_Length` in the package
`Wide_Text_IO.Editing`. See F.3.4(5)."
64
*
"The accuracy actually achieved by the complex elementary
functions and by other complex arithmetic operations. See G.1(1)."
Standard library functions are used for the complex arithmetic
operations. Only fast math mode is currently supported.
*
"The sign of a zero result (or a component thereof) from
any operator or function in `Numerics.Generic_Complex_Types`, when
`Real'Signed_Zeros` is True. See G.1.1(53)."
The signs of zero values are as recommended by the relevant
implementation advice.
*
"The sign of a zero result (or a component thereof) from
any operator or function in
`Numerics.Generic_Complex_Elementary_Functions`, when
`Real'Signed_Zeros` is `True`. See G.1.2(45)."
The signs of zero values are as recommended by the relevant
implementation advice.
*
"Whether the strict mode or the relaxed mode is the
default. See G.2(2)."
The strict mode is the default. There is no separate relaxed mode. GNAT
provides a highly efficient implementation of strict mode.
*
"The result interval in certain cases of fixed-to-float
conversion. See G.2.1(10)."
For cases where the result interval is implementation dependent, the
accuracy is that provided by performing all operations in 64-bit IEEE
floating-point format.
*
"The result of a floating point arithmetic operation in
overflow situations, when the `Machine_Overflows` attribute of the
result type is `False`. See G.2.1(13)."
Infinite and NaN values are produced as dictated by the IEEE
floating-point standard.
Note that on machines that are not fully compliant with the IEEE
floating-point standard, such as Alpha, the *-mieee* compiler flag
must be used for achieving IEEE conforming behavior (although at the cost
of a significant performance penalty), so infinite and NaN values are
properly generated.
*
"The result interval for division (or exponentiation by a
negative exponent), when the floating point hardware implements division
as multiplication by a reciprocal. See G.2.1(16)."
Not relevant, division is IEEE exact.
*
"The definition of close result set, which determines the
accuracy of certain fixed point multiplications and divisions. See
G.2.3(5)."
Operations in the close result set are performed using IEEE long format
floating-point arithmetic. The input operands are converted to
floating-point, the operation is done in floating-point, and the result
is converted to the target type.
*
"Conditions on a `universal_real` operand of a fixed
point multiplication or division for which the result shall be in the
perfect result set. See G.2.3(22)."
The result is only defined to be in the perfect result set if the result
can be computed by a single scaling operation involving a scale factor
representable in 64-bits.
*
"The result of a fixed point arithmetic operation in
overflow situations, when the `Machine_Overflows` attribute of the
result type is `False`. See G.2.3(27)."
Not relevant, `Machine_Overflows` is `True` for fixed-point
types.
*
"The result of an elementary function reference in
overflow situations, when the `Machine_Overflows` attribute of the
result type is `False`. See G.2.4(4)."
IEEE infinite and Nan values are produced as appropriate.
*
"The value of the angle threshold, within which certain
elementary functions, complex arithmetic operations, and complex
elementary functions yield results conforming to a maximum relative
error bound. See G.2.4(10)."
Information on this subject is not yet available.
*
"The accuracy of certain elementary functions for
parameters beyond the angle threshold. See G.2.4(10)."
Information on this subject is not yet available.
*
"The result of a complex arithmetic operation or complex
elementary function reference in overflow situations, when the
`Machine_Overflows` attribute of the corresponding real type is
`False`. See G.2.6(5)."
IEEE infinite and Nan values are produced as appropriate.
*
"The accuracy of certain complex arithmetic operations and
certain complex elementary functions for parameters (or components
thereof) beyond the angle threshold. See G.2.6(8)."
Information on those subjects is not yet available.
*
"Information regarding bounded errors and erroneous
execution. See H.2(1)."
Information on this subject is not yet available.
*
"Implementation-defined aspects of pragma
`Inspection_Point`. See H.3.2(8)."
Pragma `Inspection_Point` ensures that the variable is live and can
be examined by the debugger at the inspection point.
*
"Implementation-defined aspects of pragma
`Restrictions`. See H.4(25)."
There are no implementation-defined aspects of pragma `Restrictions`. The
use of pragma `Restrictions [No_Exceptions]` has no effect on the
generated code. Checks must suppressed by use of pragma `Suppress`.
*
"Any restrictions on pragma `Restrictions`. See
H.4(27)."
There are no restrictions on pragma `Restrictions`.
This source diff could not be displayed because it is too large. You can view the blob instead.
.. _Implementation_of_Ada_2012_Features:
***********************************
Implementation of Ada 2012 Features
***********************************
.. index:: Ada 2012 implementation status
.. index:: -gnat12 option (gcc)
.. index:: pragma Ada_2012
.. index:: configuration pragma Ada_2012
.. index:: Ada_2012 configuration pragma
This chapter contains a complete list of Ada 2012 features that have been
implemented as of GNAT version 6.4. Generally, these features are only
available if the *-gnat12* (Ada 2012 features enabled) flag is set
or if the configuration pragma `Ada_2012` is used.
However, new pragmas, attributes, and restrictions are
unconditionally available, since the Ada 95 standard allows the addition of
new pragmas, attributes, and restrictions (there are exceptions, which are
documented in the individual descriptions), and also certain packages
were made available in earlier versions of Ada.
An ISO date (YYYY-MM-DD) appears in parentheses on the description line.
This date shows the implementation date of the feature. Any wavefront
subsequent to this date will contain the indicated feature, as will any
subsequent releases. A date of 0000-00-00 means that GNAT has always
implemented the feature, or implemented it as soon as it appeared as a
binding interpretation.
Each feature corresponds to an Ada Issue ('AI') approved by the Ada
standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2012.
The features are ordered based on the relevant sections of the Ada
Reference Manual ("RM"). When a given AI relates to multiple points
in the RM, the earliest is used.
A complete description of the AIs may be found in
http://www.ada-auth.org/ai05-summary.html.
.. index:: AI-0176 (Ada 2012 feature)
* *AI-0176 Quantified expressions (2010-09-29)*
Both universally and existentially quantified expressions are implemented.
They use the new syntax for iterators proposed in AI05-139-2, as well as
the standard Ada loop syntax.
RM References: 1.01.04 (12) 2.09 (2/2) 4.04 (7) 4.05.09 (0)
.. index:: AI-0079 (Ada 2012 feature)
* *AI-0079 Allow other_format characters in source (2010-07-10)*
Wide characters in the unicode category *other_format* are now allowed in
source programs between tokens, but not within a token such as an identifier.
RM References: 2.01 (4/2) 2.02 (7)
.. index:: AI-0091 (Ada 2012 feature)
* *AI-0091 Do not allow other_format in identifiers (0000-00-00)*
Wide characters in the unicode category *other_format* are not permitted
within an identifier, since this can be a security problem. The error
message for this case has been improved to be more specific, but GNAT has
never allowed such characters to appear in identifiers.
RM References: 2.03 (3.1/2) 2.03 (4/2) 2.03 (5/2) 2.03 (5.1/2) 2.03 (5.2/2) 2.03 (5.3/2) 2.09 (2/2)
.. index:: AI-0100 (Ada 2012 feature)
* *AI-0100 Placement of pragmas (2010-07-01)*
This AI is an earlier version of AI-163. It simplifies the rules
for legal placement of pragmas. In the case of lists that allow pragmas, if
the list may have no elements, then the list may consist solely of pragmas.
RM References: 2.08 (7)
.. index:: AI-0163 (Ada 2012 feature)
* *AI-0163 Pragmas in place of null (2010-07-01)*
A statement sequence may be composed entirely of pragmas. It is no longer
necessary to add a dummy `null` statement to make the sequence legal.
RM References: 2.08 (7) 2.08 (16)
.. index:: AI-0080 (Ada 2012 feature)
* *AI-0080 'View of' not needed if clear from context (0000-00-00)*
This is an editorial change only, described as non-testable in the AI.
RM References: 3.01 (7)
.. index:: AI-0183 (Ada 2012 feature)
* *AI-0183 Aspect specifications (2010-08-16)*
Aspect specifications have been fully implemented except for pre and post-
conditions, and type invariants, which have their own separate AI's. All
forms of declarations listed in the AI are supported. The following is a
list of the aspects supported (with GNAT implementation aspects marked)
================================== ===========
Supported Aspect Source
================================== ===========
`Ada_2005` -- GNAT
`Ada_2012` -- GNAT
`Address`
`Alignment`
`Atomic`
`Atomic_Components`
`Bit_Order`
`Component_Size`
`Contract_Cases` -- GNAT
`Discard_Names`
`External_Tag`
`Favor_Top_Level` -- GNAT
`Inline`
`Inline_Always` -- GNAT
`Invariant` -- GNAT
`Machine_Radix`
`No_Return`
`Object_Size` -- GNAT
`Pack`
`Persistent_BSS` -- GNAT
`Post`
`Pre`
`Predicate`
`Preelaborable_Initialization`
`Pure_Function` -- GNAT
`Remote_Access_Type` -- GNAT
`Shared` -- GNAT
`Size`
`Storage_Pool`
`Storage_Size`
`Stream_Size`
`Suppress`
`Suppress_Debug_Info` -- GNAT
`Test_Case` -- GNAT
`Thread_Local_Storage` -- GNAT
`Type_Invariant`
`Unchecked_Union`
`Universal_Aliasing` -- GNAT
`Unmodified` -- GNAT
`Unreferenced` -- GNAT
`Unreferenced_Objects` -- GNAT
`Unsuppress`
`Value_Size` -- GNAT
`Volatile`
`Volatile_Components`
`Warnings` -- GNAT
================================== ===========
Note that for aspects with an expression, e.g. `Size`, the expression is
treated like a default expression (visibility is analyzed at the point of
occurrence of the aspect, but evaluation of the expression occurs at the
freeze point of the entity involved).
RM References: 3.02.01 (3) 3.02.02 (2) 3.03.01 (2/2) 3.08 (6)
3.09.03 (1.1/2) 6.01 (2/2) 6.07 (2/2) 9.05.02 (2/2) 7.01 (3) 7.03
(2) 7.03 (3) 9.01 (2/2) 9.01 (3/2) 9.04 (2/2) 9.04 (3/2)
9.05.02 (2/2) 11.01 (2) 12.01 (3) 12.03 (2/2) 12.04 (2/2) 12.05 (2)
12.06 (2.1/2) 12.06 (2.2/2) 12.07 (2) 13.01 (0.1/2) 13.03 (5/1)
13.03.01 (0)
.. index:: AI-0128 (Ada 2012 feature)
* *AI-0128 Inequality is a primitive operation (0000-00-00)*
If an equality operator ("=") is declared for a type, then the implicitly
declared inequality operator ("/=") is a primitive operation of the type.
This is the only reasonable interpretation, and is the one always implemented
by GNAT, but the RM was not entirely clear in making this point.
RM References: 3.02.03 (6) 6.06 (6)
.. index:: AI-0003 (Ada 2012 feature)
* *AI-0003 Qualified expressions as names (2010-07-11)*
In Ada 2012, a qualified expression is considered to be syntactically a name,
meaning that constructs such as `A'(F(X)).B` are now legal. This is
useful in disambiguating some cases of overloading.
RM References: 3.03 (11) 3.03 (21) 4.01 (2) 4.04 (7) 4.07 (3)
5.04 (7)
.. index:: AI-0120 (Ada 2012 feature)
* *AI-0120 Constant instance of protected object (0000-00-00)*
This is an RM editorial change only. The section that lists objects that are
constant failed to include the current instance of a protected object
within a protected function. This has always been treated as a constant
in GNAT.
RM References: 3.03 (21)
.. index:: AI-0008 (Ada 2012 feature)
* *AI-0008 General access to constrained objects (0000-00-00)*
The wording in the RM implied that if you have a general access to a
constrained object, it could be used to modify the discriminants. This was
obviously not intended. `Constraint_Error` should be raised, and GNAT
has always done so in this situation.
RM References: 3.03 (23) 3.10.02 (26/2) 4.01 (9) 6.04.01 (17) 8.05.01 (5/2)
.. index:: AI-0093 (Ada 2012 feature)
* *AI-0093 Additional rules use immutably limited (0000-00-00)*
This is an editorial change only, to make more widespread use of the Ada 2012
'immutably limited'.
RM References: 3.03 (23.4/3)
.. index:: AI-0096 (Ada 2012 feature)
* *AI-0096 Deriving from formal private types (2010-07-20)*
In general it is illegal for a type derived from a formal limited type to be
nonlimited. This AI makes an exception to this rule: derivation is legal
if it appears in the private part of the generic, and the formal type is not
tagged. If the type is tagged, the legality check must be applied to the
private part of the package.
RM References: 3.04 (5.1/2) 6.02 (7)
.. index:: AI-0181 (Ada 2012 feature)
* *AI-0181 Soft hyphen is a non-graphic character (2010-07-23)*
From Ada 2005 on, soft hyphen is considered a non-graphic character, which
means that it has a special name (`SOFT_HYPHEN`) in conjunction with the
`Image` and `Value` attributes for the character types. Strictly
speaking this is an inconsistency with Ada 95, but in practice the use of
these attributes is so obscure that it will not cause problems.
RM References: 3.05.02 (2/2) A.01 (35/2) A.03.03 (21)
.. index:: AI-0182 (Ada 2012 feature)
* *AI-0182 Additional forms for `Character'Value* (0000-00-00)`
This AI allows `Character'Value` to accept the string `'?'` where
`?` is any character including non-graphic control characters. GNAT has
always accepted such strings. It also allows strings such as
`HEX_00000041` to be accepted, but GNAT does not take advantage of this
permission and raises `Constraint_Error`, as is certainly still
permitted.
RM References: 3.05 (56/2)
.. index:: AI-0214 (Ada 2012 feature)
* *AI-0214 Defaulted discriminants for limited tagged (2010-10-01)*
Ada 2012 relaxes the restriction that forbids discriminants of tagged types
to have default expressions by allowing them when the type is limited. It
is often useful to define a default value for a discriminant even though
it can't be changed by assignment.
RM References: 3.07 (9.1/2) 3.07.02 (3)
.. index:: AI-0102 (Ada 2012 feature)
* *AI-0102 Some implicit conversions are illegal (0000-00-00)*
It is illegal to assign an anonymous access constant to an anonymous access
variable. The RM did not have a clear rule to prevent this, but GNAT has
always generated an error for this usage.
RM References: 3.07 (16) 3.07.01 (9) 6.04.01 (6) 8.06 (27/2)
.. index:: AI-0158 (Ada 2012 feature)
* *AI-0158 Generalizing membership tests (2010-09-16)*
This AI extends the syntax of membership tests to simplify complex conditions
that can be expressed as membership in a subset of values of any type. It
introduces syntax for a list of expressions that may be used in loop contexts
as well.
RM References: 3.08.01 (5) 4.04 (3) 4.05.02 (3) 4.05.02 (5) 4.05.02 (27)
.. index:: AI-0173 (Ada 2012 feature)
* *AI-0173 Testing if tags represent abstract types (2010-07-03)*
The function `Ada.Tags.Type_Is_Abstract` returns `True` if invoked
with the tag of an abstract type, and `False` otherwise.
RM References: 3.09 (7.4/2) 3.09 (12.4/2)
.. index:: AI-0076 (Ada 2012 feature)
* *AI-0076 function with controlling result (0000-00-00)*
This is an editorial change only. The RM defines calls with controlling
results, but uses the term 'function with controlling result' without an
explicit definition.
RM References: 3.09.02 (2/2)
.. index:: AI-0126 (Ada 2012 feature)
* *AI-0126 Dispatching with no declared operation (0000-00-00)*
This AI clarifies dispatching rules, and simply confirms that dispatching
executes the operation of the parent type when there is no explicitly or
implicitly declared operation for the descendant type. This has always been
the case in all versions of GNAT.
RM References: 3.09.02 (20/2) 3.09.02 (20.1/2) 3.09.02 (20.2/2)
.. index:: AI-0097 (Ada 2012 feature)
* *AI-0097 Treatment of abstract null extension (2010-07-19)*
The RM as written implied that in some cases it was possible to create an
object of an abstract type, by having an abstract extension inherit a non-
abstract constructor from its parent type. This mistake has been corrected
in GNAT and in the RM, and this construct is now illegal.
RM References: 3.09.03 (4/2)
.. index:: AI-0203 (Ada 2012 feature)
* *AI-0203 Extended return cannot be abstract (0000-00-00)*
A return_subtype_indication cannot denote an abstract subtype. GNAT has never
permitted such usage.
RM References: 3.09.03 (8/3)
.. index:: AI-0198 (Ada 2012 feature)
* *AI-0198 Inheriting abstract operators (0000-00-00)*
This AI resolves a conflict between two rules involving inherited abstract
operations and predefined operators. If a derived numeric type inherits
an abstract operator, it overrides the predefined one. This interpretation
was always the one implemented in GNAT.
RM References: 3.09.03 (4/3)
.. index:: AI-0073 (Ada 2012 feature)
* *AI-0073 Functions returning abstract types (2010-07-10)*
This AI covers a number of issues regarding returning abstract types. In
particular generic functions cannot have abstract result types or access
result types designated an abstract type. There are some other cases which
are detailed in the AI. Note that this binding interpretation has not been
retrofitted to operate before Ada 2012 mode, since it caused a significant
number of regressions.
RM References: 3.09.03 (8) 3.09.03 (10) 6.05 (8/2)
.. index:: AI-0070 (Ada 2012 feature)
* *AI-0070 Elaboration of interface types (0000-00-00)*
This is an editorial change only, there are no testable consequences short of
checking for the absence of generated code for an interface declaration.
RM References: 3.09.04 (18/2)
.. index:: AI-0208 (Ada 2012 feature)
* *AI-0208 Characteristics of incomplete views (0000-00-00)*
The wording in the Ada 2005 RM concerning characteristics of incomplete views
was incorrect and implied that some programs intended to be legal were now
illegal. GNAT had never considered such programs illegal, so it has always
implemented the intent of this AI.
RM References: 3.10.01 (2.4/2) 3.10.01 (2.6/2)
.. index:: AI-0162 (Ada 2012 feature)
* *AI-0162 Incomplete type completed by partial view (2010-09-15)*
Incomplete types are made more useful by allowing them to be completed by
private types and private extensions.
RM References: 3.10.01 (2.5/2) 3.10.01 (2.6/2) 3.10.01 (3) 3.10.01 (4/2)
.. index:: AI-0098 (Ada 2012 feature)
* *AI-0098 Anonymous subprogram access restrictions (0000-00-00)*
An unintentional omission in the RM implied some inconsistent restrictions on
the use of anonymous access to subprogram values. These restrictions were not
intentional, and have never been enforced by GNAT.
RM References: 3.10.01 (6) 3.10.01 (9.2/2)
.. index:: AI-0199 (Ada 2012 feature)
* *AI-0199 Aggregate with anonymous access components (2010-07-14)*
A choice list in a record aggregate can include several components of
(distinct) anonymous access types as long as they have matching designated
subtypes.
RM References: 4.03.01 (16)
.. index:: AI-0220 (Ada 2012 feature)
* *AI-0220 Needed components for aggregates (0000-00-00)*
This AI addresses a wording problem in the RM that appears to permit some
complex cases of aggregates with non-static discriminants. GNAT has always
implemented the intended semantics.
RM References: 4.03.01 (17)
.. index:: AI-0147 (Ada 2012 feature)
* *AI-0147 Conditional expressions (2009-03-29)*
Conditional expressions are permitted. The form of such an expression is:
::
(if expr then expr {elsif expr then expr} [else expr])
The parentheses can be omitted in contexts where parentheses are present
anyway, such as subprogram arguments and pragma arguments. If the **else**
clause is omitted, **else** *True* is assumed;
thus ``(if A then B)`` is a way to conveniently represent
*(A implies B)* in standard logic.
RM References: 4.03.03 (15) 4.04 (1) 4.04 (7) 4.05.07 (0) 4.07 (2)
4.07 (3) 4.09 (12) 4.09 (33) 5.03 (3) 5.03 (4) 7.05 (2.1/2)
.. index:: AI-0037 (Ada 2012 feature)
* *AI-0037 Out-of-range box associations in aggregate (0000-00-00)*
This AI confirms that an association of the form `Indx => <>` in an
array aggregate must raise `Constraint_Error` if `Indx`
is out of range. The RM specified a range check on other associations, but
not when the value of the association was defaulted. GNAT has always inserted
a constraint check on the index value.
RM References: 4.03.03 (29)
.. index:: AI-0123 (Ada 2012 feature)
* *AI-0123 Composability of equality (2010-04-13)*
Equality of untagged record composes, so that the predefined equality for a
composite type that includes a component of some untagged record type
`R` uses the equality operation of `R` (which may be user-defined
or predefined). This makes the behavior of untagged records identical to that
of tagged types in this respect.
This change is an incompatibility with previous versions of Ada, but it
corrects a non-uniformity that was often a source of confusion. Analysis of
a large number of industrial programs indicates that in those rare cases
where a composite type had an untagged record component with a user-defined
equality, either there was no use of the composite equality, or else the code
expected the same composability as for tagged types, and thus had a bug that
would be fixed by this change.
RM References: 4.05.02 (9.7/2) 4.05.02 (14) 4.05.02 (15) 4.05.02 (24)
8.05.04 (8)
.. index:: AI-0088 (Ada 2012 feature)
* *AI-0088 The value of exponentiation (0000-00-00)*
This AI clarifies the equivalence rule given for the dynamic semantics of
exponentiation: the value of the operation can be obtained by repeated
multiplication, but the operation can be implemented otherwise (for example
using the familiar divide-by-two-and-square algorithm, even if this is less
accurate), and does not imply repeated reads of a volatile base.
RM References: 4.05.06 (11)
.. index:: AI-0188 (Ada 2012 feature)
* *AI-0188 Case expressions (2010-01-09)*
Case expressions are permitted. This allows use of constructs such as:
.. code-block:: ada
X := (case Y is when 1 => 2, when 2 => 3, when others => 31)
RM References: 4.05.07 (0) 4.05.08 (0) 4.09 (12) 4.09 (33)
.. index:: AI-0104 (Ada 2012 feature)
* *AI-0104 Null exclusion and uninitialized allocator (2010-07-15)*
The assignment ``Ptr := new not null Some_Ptr;`` will raise
``Constraint_Error`` because the default value of the allocated object is
**null**. This useless construct is illegal in Ada 2012.
RM References: 4.08 (2)
.. index:: AI-0157 (Ada 2012 feature)
* *AI-0157 Allocation/Deallocation from empty pool (2010-07-11)*
Allocation and Deallocation from an empty storage pool (i.e. allocation or
deallocation of a pointer for which a static storage size clause of zero
has been given) is now illegal and is detected as such. GNAT
previously gave a warning but not an error.
RM References: 4.08 (5.3/2) 13.11.02 (4) 13.11.02 (17)
.. index:: AI-0179 (Ada 2012 feature)
* *AI-0179 Statement not required after label (2010-04-10)*
It is not necessary to have a statement following a label, so a label
can appear at the end of a statement sequence without the need for putting a
null statement afterwards, but it is not allowable to have only labels and
no real statements in a statement sequence.
RM References: 5.01 (2)
.. index:: AI-0139-2 (Ada 2012 feature)
* *AI-0139-2 Syntactic sugar for iterators (2010-09-29)*
The new syntax for iterating over arrays and containers is now implemented.
Iteration over containers is for now limited to read-only iterators. Only
default iterators are supported, with the syntax: `for Elem of C`.
RM References: 5.05
.. index:: AI-0134 (Ada 2012 feature)
* *AI-0134 Profiles must match for full conformance (0000-00-00)*
For full conformance, the profiles of anonymous-access-to-subprogram
parameters must match. GNAT has always enforced this rule.
RM References: 6.03.01 (18)
.. index:: AI-0207 (Ada 2012 feature)
* *AI-0207 Mode conformance and access constant (0000-00-00)*
This AI confirms that access_to_constant indication must match for mode
conformance. This was implemented in GNAT when the qualifier was originally
introduced in Ada 2005.
RM References: 6.03.01 (16/2)
.. index:: AI-0046 (Ada 2012 feature)
* *AI-0046 Null exclusion match for full conformance (2010-07-17)*
For full conformance, in the case of access parameters, the null exclusion
must match (either both or neither must have ``not null``).
RM References: 6.03.02 (18)
.. index:: AI-0118 (Ada 2012 feature)
* *AI-0118 The association of parameter associations (0000-00-00)*
This AI clarifies the rules for named associations in subprogram calls and
generic instantiations. The rules have been in place since Ada 83.
RM References: 6.04.01 (2) 12.03 (9)
.. index:: AI-0196 (Ada 2012 feature)
* *AI-0196 Null exclusion tests for out parameters (0000-00-00)*
Null exclusion checks are not made for `**out**` parameters when
evaluating the actual parameters. GNAT has never generated these checks.
RM References: 6.04.01 (13)
.. index:: AI-0015 (Ada 2012 feature)
* *AI-0015 Constant return objects (0000-00-00)*
The return object declared in an *extended_return_statement* may be
declared constant. This was always intended, and GNAT has always allowed it.
RM References: 6.05 (2.1/2) 3.03 (10/2) 3.03 (21) 6.05 (5/2)
6.05 (5.7/2)
.. index:: AI-0032 (Ada 2012 feature)
* *AI-0032 Extended return for class-wide functions (0000-00-00)*
If a function returns a class-wide type, the object of an extended return
statement can be declared with a specific type that is covered by the class-
wide type. This has been implemented in GNAT since the introduction of
extended returns. Note AI-0103 complements this AI by imposing matching
rules for constrained return types.
RM References: 6.05 (5.2/2) 6.05 (5.3/2) 6.05 (5.6/2) 6.05 (5.8/2)
6.05 (8/2)
.. index:: AI-0103 (Ada 2012 feature)
* *AI-0103 Static matching for extended return (2010-07-23)*
If the return subtype of a function is an elementary type or a constrained
type, the subtype indication in an extended return statement must match
statically this return subtype.
RM References: 6.05 (5.2/2)
.. index:: AI-0058 (Ada 2012 feature)
* *AI-0058 Abnormal completion of an extended return (0000-00-00)*
The RM had some incorrect wording implying wrong treatment of abnormal
completion in an extended return. GNAT has always implemented the intended
correct semantics as described by this AI.
RM References: 6.05 (22/2)
.. index:: AI-0050 (Ada 2012 feature)
* *AI-0050 Raising Constraint_Error early for function call (0000-00-00)*
The implementation permissions for raising `Constraint_Error` early on a function call
when it was clear an exception would be raised were over-permissive and allowed
mishandling of discriminants in some cases. GNAT did
not take advantage of these incorrect permissions in any case.
RM References: 6.05 (24/2)
.. index:: AI-0125 (Ada 2012 feature)
* *AI-0125 Nonoverridable operations of an ancestor (2010-09-28)*
In Ada 2012, the declaration of a primitive operation of a type extension
or private extension can also override an inherited primitive that is not
visible at the point of this declaration.
RM References: 7.03.01 (6) 8.03 (23) 8.03.01 (5/2) 8.03.01 (6/2)
.. index:: AI-0062 (Ada 2012 feature)
* *AI-0062 Null exclusions and deferred constants (0000-00-00)*
A full constant may have a null exclusion even if its associated deferred
constant does not. GNAT has always allowed this.
RM References: 7.04 (6/2) 7.04 (7.1/2)
.. index:: AI-0178 (Ada 2012 feature)
* *AI-0178 Incomplete views are limited (0000-00-00)*
This AI clarifies the role of incomplete views and plugs an omission in the
RM. GNAT always correctly restricted the use of incomplete views and types.
RM References: 7.05 (3/2) 7.05 (6/2)
.. index:: AI-0087 (Ada 2012 feature)
* *AI-0087 Actual for formal nonlimited derived type (2010-07-15)*
The actual for a formal nonlimited derived type cannot be limited. In
particular, a formal derived type that extends a limited interface but which
is not explicitly limited cannot be instantiated with a limited type.
RM References: 7.05 (5/2) 12.05.01 (5.1/2)
.. index:: AI-0099 (Ada 2012 feature)
* *AI-0099 Tag determines whether finalization needed (0000-00-00)*
This AI clarifies that 'needs finalization' is part of dynamic semantics,
and therefore depends on the run-time characteristics of an object (i.e. its
tag) and not on its nominal type. As the AI indicates: "we do not expect
this to affect any implementation''.
RM References: 7.06.01 (6) 7.06.01 (7) 7.06.01 (8) 7.06.01 (9/2)
.. index:: AI-0064 (Ada 2012 feature)
* *AI-0064 Redundant finalization rule (0000-00-00)*
This is an editorial change only. The intended behavior is already checked
by an existing ACATS test, which GNAT has always executed correctly.
RM References: 7.06.01 (17.1/1)
.. index:: AI-0026 (Ada 2012 feature)
* *AI-0026 Missing rules for Unchecked_Union (2010-07-07)*
Record representation clauses concerning Unchecked_Union types cannot mention
the discriminant of the type. The type of a component declared in the variant
part of an Unchecked_Union cannot be controlled, have controlled components,
nor have protected or task parts. If an Unchecked_Union type is declared
within the body of a generic unit or its descendants, then the type of a
component declared in the variant part cannot be a formal private type or a
formal private extension declared within the same generic unit.
RM References: 7.06 (9.4/2) B.03.03 (9/2) B.03.03 (10/2)
.. index:: AI-0205 (Ada 2012 feature)
* *AI-0205 Extended return declares visible name (0000-00-00)*
This AI corrects a simple omission in the RM. Return objects have always
been visible within an extended return statement.
RM References: 8.03 (17)
.. index:: AI-0042 (Ada 2012 feature)
* *AI-0042 Overriding versus implemented-by (0000-00-00)*
This AI fixes a wording gap in the RM. An operation of a synchronized
interface can be implemented by a protected or task entry, but the abstract
operation is not being overridden in the usual sense, and it must be stated
separately that this implementation is legal. This has always been the case
in GNAT.
RM References: 9.01 (9.2/2) 9.04 (11.1/2)
.. index:: AI-0030 (Ada 2012 feature)
* *AI-0030 Requeue on synchronized interfaces (2010-07-19)*
Requeue is permitted to a protected, synchronized or task interface primitive
providing it is known that the overriding operation is an entry. Otherwise
the requeue statement has the same effect as a procedure call. Use of pragma
`Implemented` provides a way to impose a static requirement on the
overriding operation by adhering to one of the implementation kinds: entry,
protected procedure or any of the above.
RM References: 9.05 (9) 9.05.04 (2) 9.05.04 (3) 9.05.04 (5)
9.05.04 (6) 9.05.04 (7) 9.05.04 (12)
.. index:: AI-0201 (Ada 2012 feature)
* *AI-0201 Independence of atomic object components (2010-07-22)*
If an Atomic object has a pragma `Pack` or a `Component_Size`
attribute, then individual components may not be addressable by independent
tasks. However, if the representation clause has no effect (is confirming),
then independence is not compromised. Furthermore, in GNAT, specification of
other appropriately addressable component sizes (e.g. 16 for 8-bit
characters) also preserves independence. GNAT now gives very clear warnings
both for the declaration of such a type, and for any assignment to its components.
RM References: 9.10 (1/3) C.06 (22/2) C.06 (23/2)
.. index:: AI-0009 (Ada 2012 feature)
* *AI-0009 Pragma Independent[_Components] (2010-07-23)*
This AI introduces the new pragmas `Independent` and
`Independent_Components`,
which control guaranteeing independence of access to objects and components.
The AI also requires independence not unaffected by confirming rep clauses.
RM References: 9.10 (1) 13.01 (15/1) 13.02 (9) 13.03 (13) C.06 (2)
C.06 (4) C.06 (6) C.06 (9) C.06 (13) C.06 (14)
.. index:: AI-0072 (Ada 2012 feature)
* *AI-0072 Task signalling using 'Terminated (0000-00-00)*
This AI clarifies that task signalling for reading `'Terminated` only
occurs if the result is True. GNAT semantics has always been consistent with
this notion of task signalling.
RM References: 9.10 (6.1/1)
.. index:: AI-0108 (Ada 2012 feature)
* *AI-0108 Limited incomplete view and discriminants (0000-00-00)*
This AI confirms that an incomplete type from a limited view does not have
discriminants. This has always been the case in GNAT.
RM References: 10.01.01 (12.3/2)
.. index:: AI-0129 (Ada 2012 feature)
* *AI-0129 Limited views and incomplete types (0000-00-00)*
This AI clarifies the description of limited views: a limited view of a
package includes only one view of a type that has an incomplete declaration
and a full declaration (there is no possible ambiguity in a client package).
This AI also fixes an omission: a nested package in the private part has no
limited view. GNAT always implemented this correctly.
RM References: 10.01.01 (12.2/2) 10.01.01 (12.3/2)
.. index:: AI-0077 (Ada 2012 feature)
* *AI-0077 Limited withs and scope of declarations (0000-00-00)*
This AI clarifies that a declaration does not include a context clause,
and confirms that it is illegal to have a context in which both a limited
and a nonlimited view of a package are accessible. Such double visibility
was always rejected by GNAT.
RM References: 10.01.02 (12/2) 10.01.02 (21/2) 10.01.02 (22/2)
.. index:: AI-0122 (Ada 2012 feature)
* *AI-0122 Private with and children of generics (0000-00-00)*
This AI clarifies the visibility of private children of generic units within
instantiations of a parent. GNAT has always handled this correctly.
RM References: 10.01.02 (12/2)
.. index:: AI-0040 (Ada 2012 feature)
* *AI-0040 Limited with clauses on descendant (0000-00-00)*
This AI confirms that a limited with clause in a child unit cannot name
an ancestor of the unit. This has always been checked in GNAT.
RM References: 10.01.02 (20/2)
.. index:: AI-0132 (Ada 2012 feature)
* *AI-0132 Placement of library unit pragmas (0000-00-00)*
This AI fills a gap in the description of library unit pragmas. The pragma
clearly must apply to a library unit, even if it does not carry the name
of the enclosing unit. GNAT has always enforced the required check.
RM References: 10.01.05 (7)
.. index:: AI-0034 (Ada 2012 feature)
* *AI-0034 Categorization of limited views (0000-00-00)*
The RM makes certain limited with clauses illegal because of categorization
considerations, when the corresponding normal with would be legal. This is
not intended, and GNAT has always implemented the recommended behavior.
RM References: 10.02.01 (11/1) 10.02.01 (17/2)
.. index:: AI-0035 (Ada 2012 feature)
* *AI-0035 Inconsistencies with Pure units (0000-00-00)*
This AI remedies some inconsistencies in the legality rules for Pure units.
Derived access types are legal in a pure unit (on the assumption that the
rule for a zero storage pool size has been enforced on the ancestor type).
The rules are enforced in generic instances and in subunits. GNAT has always
implemented the recommended behavior.
RM References: 10.02.01 (15.1/2) 10.02.01 (15.4/2) 10.02.01 (15.5/2) 10.02.01 (17/2)
.. index:: AI-0219 (Ada 2012 feature)
* *AI-0219 Pure permissions and limited parameters (2010-05-25)*
This AI refines the rules for the cases with limited parameters which do not
allow the implementations to omit 'redundant'. GNAT now properly conforms
to the requirements of this binding interpretation.
RM References: 10.02.01 (18/2)
.. index:: AI-0043 (Ada 2012 feature)
* *AI-0043 Rules about raising exceptions (0000-00-00)*
This AI covers various omissions in the RM regarding the raising of
exceptions. GNAT has always implemented the intended semantics.
RM References: 11.04.01 (10.1/2) 11 (2)
.. index:: AI-0200 (Ada 2012 feature)
* *AI-0200 Mismatches in formal package declarations (0000-00-00)*
This AI plugs a gap in the RM which appeared to allow some obviously intended
illegal instantiations. GNAT has never allowed these instantiations.
RM References: 12.07 (16)
.. index:: AI-0112 (Ada 2012 feature)
* *AI-0112 Detection of duplicate pragmas (2010-07-24)*
This AI concerns giving names to various representation aspects, but the
practical effect is simply to make the use of duplicate
`Atomic[_Components]`,
`Volatile[_Components]`, and
`Independent[_Components]` pragmas illegal, and GNAT
now performs this required check.
RM References: 13.01 (8)
.. index:: AI-0106 (Ada 2012 feature)
* *AI-0106 No representation pragmas on generic formals (0000-00-00)*
The RM appeared to allow representation pragmas on generic formal parameters,
but this was not intended, and GNAT has never permitted this usage.
RM References: 13.01 (9.1/1)
.. index:: AI-0012 (Ada 2012 feature)
* *AI-0012 Pack/Component_Size for aliased/atomic (2010-07-15)*
It is now illegal to give an inappropriate component size or a pragma
`Pack` that attempts to change the component size in the case of atomic
or aliased components. Previously GNAT ignored such an attempt with a
warning.
RM References: 13.02 (6.1/2) 13.02 (7) C.06 (10) C.06 (11) C.06 (21)
.. index:: AI-0039 (Ada 2012 feature)
* *AI-0039 Stream attributes cannot be dynamic (0000-00-00)*
The RM permitted the use of dynamic expressions (such as ``ptr.all``)`
for stream attributes, but these were never useful and are now illegal. GNAT
has always regarded such expressions as illegal.
RM References: 13.03 (4) 13.03 (6) 13.13.02 (38/2)
.. index:: AI-0095 (Ada 2012 feature)
* *AI-0095 Address of intrinsic subprograms (0000-00-00)*
The prefix of `'Address` cannot statically denote a subprogram with
convention `Intrinsic`. The use of the `Address` attribute raises
`Program_Error` if the prefix denotes a subprogram with convention
`Intrinsic`.
RM References: 13.03 (11/1)
.. index:: AI-0116 (Ada 2012 feature)
* *AI-0116 Alignment of class-wide objects (0000-00-00)*
This AI requires that the alignment of a class-wide object be no greater
than the alignment of any type in the class. GNAT has always followed this
recommendation.
RM References: 13.03 (29) 13.11 (16)
.. index:: AI-0146 (Ada 2012 feature)
* *AI-0146 Type invariants (2009-09-21)*
Type invariants may be specified for private types using the aspect notation.
Aspect `Type_Invariant` may be specified for any private type,
`Type_Invariant'Class` can
only be specified for tagged types, and is inherited by any descendent of the
tagged types. The invariant is a boolean expression that is tested for being
true in the following situations: conversions to the private type, object
declarations for the private type that are default initialized, and
[**in**] **out**
parameters and returned result on return from any primitive operation for
the type that is visible to a client.
GNAT defines the synonyms `Invariant` for `Type_Invariant` and
`Invariant'Class` for `Type_Invariant'Class`.
RM References: 13.03.03 (00)
.. index:: AI-0078 (Ada 2012 feature)
* *AI-0078 Relax Unchecked_Conversion alignment rules (0000-00-00)*
In Ada 2012, compilers are required to support unchecked conversion where the
target alignment is a multiple of the source alignment. GNAT always supported
this case (and indeed all cases of differing alignments, doing copies where
required if the alignment was reduced).
RM References: 13.09 (7)
.. index:: AI-0195 (Ada 2012 feature)
* *AI-0195 Invalid value handling is implementation defined (2010-07-03)*
The handling of invalid values is now designated to be implementation
defined. This is a documentation change only, requiring Annex M in the GNAT
Reference Manual to document this handling.
In GNAT, checks for invalid values are made
only when necessary to avoid erroneous behavior. Operations like assignments
which cannot cause erroneous behavior ignore the possibility of invalid
values and do not do a check. The date given above applies only to the
documentation change, this behavior has always been implemented by GNAT.
RM References: 13.09.01 (10)
.. index:: AI-0193 (Ada 2012 feature)
* *AI-0193 Alignment of allocators (2010-09-16)*
This AI introduces a new attribute `Max_Alignment_For_Allocation`,
analogous to `Max_Size_In_Storage_Elements`, but for alignment instead
of size.
RM References: 13.11 (16) 13.11 (21) 13.11.01 (0) 13.11.01 (1)
13.11.01 (2) 13.11.01 (3)
.. index:: AI-0177 (Ada 2012 feature)
* *AI-0177 Parameterized expressions (2010-07-10)*
The new Ada 2012 notion of parameterized expressions is implemented. The form
is:
.. code-block:: ada
function-specification is (expression)
This is exactly equivalent to the
corresponding function body that returns the expression, but it can appear
in a package spec. Note that the expression must be parenthesized.
RM References: 13.11.01 (3/2)
.. index:: AI-0033 (Ada 2012 feature)
* *AI-0033 Attach/Interrupt_Handler in generic (2010-07-24)*
Neither of these two pragmas may appear within a generic template, because
the generic might be instantiated at other than the library level.
RM References: 13.11.02 (16) C.03.01 (7/2) C.03.01 (8/2)
.. index:: AI-0161 (Ada 2012 feature)
* *AI-0161 Restriction No_Default_Stream_Attributes (2010-09-11)*
A new restriction `No_Default_Stream_Attributes` prevents the use of any
of the default stream attributes for elementary types. If this restriction is
in force, then it is necessary to provide explicit subprograms for any
stream attributes used.
RM References: 13.12.01 (4/2) 13.13.02 (40/2) 13.13.02 (52/2)
.. index:: AI-0194 (Ada 2012 feature)
* *AI-0194 Value of Stream_Size attribute (0000-00-00)*
The `Stream_Size` attribute returns the default number of bits in the
stream representation of the given type.
This value is not affected by the presence
of stream subprogram attributes for the type. GNAT has always implemented
this interpretation.
RM References: 13.13.02 (1.2/2)
.. index:: AI-0109 (Ada 2012 feature)
* *AI-0109 Redundant check in S'Class'Input (0000-00-00)*
This AI is an editorial change only. It removes the need for a tag check
that can never fail.
RM References: 13.13.02 (34/2)
.. index:: AI-0007 (Ada 2012 feature)
* *AI-0007 Stream read and private scalar types (0000-00-00)*
The RM as written appeared to limit the possibilities of declaring read
attribute procedures for private scalar types. This limitation was not
intended, and has never been enforced by GNAT.
RM References: 13.13.02 (50/2) 13.13.02 (51/2)
.. index:: AI-0065 (Ada 2012 feature)
* *AI-0065 Remote access types and external streaming (0000-00-00)*
This AI clarifies the fact that all remote access types support external
streaming. This fixes an obvious oversight in the definition of the
language, and GNAT always implemented the intended correct rules.
RM References: 13.13.02 (52/2)
.. index:: AI-0019 (Ada 2012 feature)
* *AI-0019 Freezing of primitives for tagged types (0000-00-00)*
The RM suggests that primitive subprograms of a specific tagged type are
frozen when the tagged type is frozen. This would be an incompatible change
and is not intended. GNAT has never attempted this kind of freezing and its
behavior is consistent with the recommendation of this AI.
RM References: 13.14 (2) 13.14 (3/1) 13.14 (8.1/1) 13.14 (10) 13.14 (14) 13.14 (15.1/2)
.. index:: AI-0017 (Ada 2012 feature)
* *AI-0017 Freezing and incomplete types (0000-00-00)*
So-called 'Taft-amendment types' (i.e., types that are completed in package
bodies) are not frozen by the occurrence of bodies in the
enclosing declarative part. GNAT always implemented this properly.
RM References: 13.14 (3/1)
.. index:: AI-0060 (Ada 2012 feature)
* *AI-0060 Extended definition of remote access types (0000-00-00)*
This AI extends the definition of remote access types to include access
to limited, synchronized, protected or task class-wide interface types.
GNAT already implemented this extension.
RM References: A (4) E.02.02 (9/1) E.02.02 (9.2/1) E.02.02 (14/2) E.02.02 (18)
.. index:: AI-0114 (Ada 2012 feature)
* *AI-0114 Classification of letters (0000-00-00)*
The code points 170 (`FEMININE ORDINAL INDICATOR`),
181 (`MICRO SIGN`), and
186 (`MASCULINE ORDINAL INDICATOR`) are technically considered
lower case letters by Unicode.
However, they are not allowed in identifiers, and they
return `False` to `Ada.Characters.Handling.Is_Letter/Is_Lower`.
This behavior is consistent with that defined in Ada 95.
RM References: A.03.02 (59) A.04.06 (7)
.. index:: AI-0185 (Ada 2012 feature)
* *AI-0185 Ada.Wide_[Wide_]Characters.Handling (2010-07-06)*
Two new packages `Ada.Wide_[Wide_]Characters.Handling` provide
classification functions for `Wide_Character` and
`Wide_Wide_Character`, as well as providing
case folding routines for `Wide_[Wide_]Character` and
`Wide_[Wide_]String`.
RM References: A.03.05 (0) A.03.06 (0)
.. index:: AI-0031 (Ada 2012 feature)
* *AI-0031 Add From parameter to Find_Token (2010-07-25)*
A new version of `Find_Token` is added to all relevant string packages,
with an extra parameter `From`. Instead of starting at the first
character of the string, the search for a matching Token starts at the
character indexed by the value of `From`.
These procedures are available in all versions of Ada
but if used in versions earlier than Ada 2012 they will generate a warning
that an Ada 2012 subprogram is being used.
RM References: A.04.03 (16) A.04.03 (67) A.04.03 (68/1) A.04.04 (51)
A.04.05 (46)
.. index:: AI-0056 (Ada 2012 feature)
* *AI-0056 Index on null string returns zero (0000-00-00)*
The wording in the Ada 2005 RM implied an incompatible handling of the
`Index` functions, resulting in raising an exception instead of
returning zero in some situations.
This was not intended and has been corrected.
GNAT always returned zero, and is thus consistent with this AI.
RM References: A.04.03 (56.2/2) A.04.03 (58.5/2)
.. index:: AI-0137 (Ada 2012 feature)
* *AI-0137 String encoding package (2010-03-25)*
The packages `Ada.Strings.UTF_Encoding`, together with its child
packages, `Conversions`, `Strings`, `Wide_Strings`,
and `Wide_Wide_Strings` have been
implemented. These packages (whose documentation can be found in the spec
files :file:`a-stuten.ads`, :file:`a-suenco.ads`, :file:`a-suenst.ads`,
:file:`a-suewst.ads`, :file:`a-suezst.ads`) allow encoding and decoding of
`String`, `Wide_String`, and `Wide_Wide_String`
values using UTF coding schemes (including UTF-8, UTF-16LE, UTF-16BE, and
UTF-16), as well as conversions between the different UTF encodings. With
the exception of `Wide_Wide_Strings`, these packages are available in
Ada 95 and Ada 2005 mode as well as Ada 2012 mode.
The `Wide_Wide_Strings package`
is available in Ada 2005 mode as well as Ada 2012 mode (but not in Ada 95
mode since it uses `Wide_Wide_Character`).
RM References: A.04.11
.. index:: AI-0038 (Ada 2012 feature)
* *AI-0038 Minor errors in Text_IO (0000-00-00)*
These are minor errors in the description on three points. The intent on
all these points has always been clear, and GNAT has always implemented the
correct intended semantics.
RM References: A.10.05 (37) A.10.07 (8/1) A.10.07 (10) A.10.07 (12) A.10.08 (10) A.10.08 (24)
.. index:: AI-0044 (Ada 2012 feature)
* *AI-0044 Restrictions on container instantiations (0000-00-00)*
This AI places restrictions on allowed instantiations of generic containers.
These restrictions are not checked by the compiler, so there is nothing to
change in the implementation. This affects only the RM documentation.
RM References: A.18 (4/2) A.18.02 (231/2) A.18.03 (145/2) A.18.06 (56/2) A.18.08 (66/2) A.18.09 (79/2) A.18.26 (5/2) A.18.26 (9/2)
.. index:: AI-0127 (Ada 2012 feature)
* *AI-0127 Adding Locale Capabilities (2010-09-29)*
This package provides an interface for identifying the current locale.
RM References: A.19 A.19.01 A.19.02 A.19.03 A.19.05 A.19.06
A.19.07 A.19.08 A.19.09 A.19.10 A.19.11 A.19.12 A.19.13
.. index:: AI-0002 (Ada 2012 feature)
* *AI-0002 Export C with unconstrained arrays (0000-00-00)*
The compiler is not required to support exporting an Ada subprogram with
convention C if there are parameters or a return type of an unconstrained
array type (such as `String`). GNAT allows such declarations but
generates warnings. It is possible, but complicated, to write the
corresponding C code and certainly such code would be specific to GNAT and
non-portable.
RM References: B.01 (17) B.03 (62) B.03 (71.1/2)
.. index:: AI05-0216 (Ada 2012 feature)
* *AI-0216 No_Task_Hierarchy forbids local tasks (0000-00-00)*
It is clearly the intention that `No_Task_Hierarchy` is intended to
forbid tasks declared locally within subprograms, or functions returning task
objects, and that is the implementation that GNAT has always provided.
However the language in the RM was not sufficiently clear on this point.
Thus this is a documentation change in the RM only.
RM References: D.07 (3/3)
.. index:: AI-0211 (Ada 2012 feature)
* *AI-0211 No_Relative_Delays forbids Set_Handler use (2010-07-09)*
The restriction `No_Relative_Delays` forbids any calls to the subprogram
`Ada.Real_Time.Timing_Events.Set_Handler`.
RM References: D.07 (5) D.07 (10/2) D.07 (10.4/2) D.07 (10.7/2)
.. index:: AI-0190 (Ada 2012 feature)
* *AI-0190 pragma Default_Storage_Pool (2010-09-15)*
This AI introduces a new pragma `Default_Storage_Pool`, which can be
used to control storage pools globally.
In particular, you can force every access
type that is used for allocation (**new**) to have an explicit storage pool,
or you can declare a pool globally to be used for all access types that lack
an explicit one.
RM References: D.07 (8)
.. index:: AI-0189 (Ada 2012 feature)
* *AI-0189 No_Allocators_After_Elaboration (2010-01-23)*
This AI introduces a new restriction `No_Allocators_After_Elaboration`,
which says that no dynamic allocation will occur once elaboration is
completed.
In general this requires a run-time check, which is not required, and which
GNAT does not attempt. But the static cases of allocators in a task body or
in the body of the main program are detected and flagged at compile or bind
time.
RM References: D.07 (19.1/2) H.04 (23.3/2)
.. index:: AI-0171 (Ada 2012 feature)
* *AI-0171 Pragma CPU and Ravenscar Profile (2010-09-24)*
A new package `System.Multiprocessors` is added, together with the
definition of pragma `CPU` for controlling task affinity. A new no
dependence restriction, on `System.Multiprocessors.Dispatching_Domains`,
is added to the Ravenscar profile.
RM References: D.13.01 (4/2) D.16
.. index:: AI-0210 (Ada 2012 feature)
* *AI-0210 Correct Timing_Events metric (0000-00-00)*
This is a documentation only issue regarding wording of metric requirements,
that does not affect the implementation of the compiler.
RM References: D.15 (24/2)
.. index:: AI-0206 (Ada 2012 feature)
* *AI-0206 Remote types packages and preelaborate (2010-07-24)*
Remote types packages are now allowed to depend on preelaborated packages.
This was formerly considered illegal.
RM References: E.02.02 (6)
.. index:: AI-0152 (Ada 2012 feature)
* *AI-0152 Restriction No_Anonymous_Allocators (2010-09-08)*
Restriction `No_Anonymous_Allocators` prevents the use of allocators
where the type of the returned value is an anonymous access type.
RM References: H.04 (8/1)
.. _Implementation_of_Specific_Ada_Features:
***************************************
Implementation of Specific Ada Features
***************************************
This chapter describes the GNAT implementation of several Ada language
facilities.
.. _Machine_Code_Insertions:
Machine Code Insertions
=======================
.. index:: Machine Code insertions
Package `Machine_Code` provides machine code support as described
in the Ada Reference Manual in two separate forms:
*
Machine code statements, consisting of qualified expressions that
fit the requirements of RM section 13.8.
*
An intrinsic callable procedure, providing an alternative mechanism of
including machine instructions in a subprogram.
The two features are similar, and both are closely related to the mechanism
provided by the asm instruction in the GNU C compiler. Full understanding
and use of the facilities in this package requires understanding the asm
instruction, see the section on Extended Asm in
:title:`Using_the_GNU_Compiler_Collection_(GCC)`.
Calls to the function `Asm` and the procedure `Asm` have identical
semantic restrictions and effects as described below. Both are provided so
that the procedure call can be used as a statement, and the function call
can be used to form a code_statement.
Consider this C `asm` instruction:
::
asm ("fsinx %1 %0" : "=f" (result) : "f" (angle));
The equivalent can be written for GNAT as:
.. code-block:: ada
Asm ("fsinx %1 %0",
My_Float'Asm_Output ("=f", result),
My_Float'Asm_Input ("f", angle));
The first argument to `Asm` is the assembler template, and is
identical to what is used in GNU C. This string must be a static
expression. The second argument is the output operand list. It is
either a single `Asm_Output` attribute reference, or a list of such
references enclosed in parentheses (technically an array aggregate of
such references).
The `Asm_Output` attribute denotes a function that takes two
parameters. The first is a string, the second is the name of a variable
of the type designated by the attribute prefix. The first (string)
argument is required to be a static expression and designates the
constraint (see the section on Constraints in
:title:`Using_the_GNU_Compiler_Collection_(GCC)`)
for the parameter; e.g., what kind of register is required. The second
argument is the variable to be written or updated with the
result. The possible values for constraint are the same as those used in
the RTL, and are dependent on the configuration file used to build the
GCC back end. If there are no output operands, then this argument may
either be omitted, or explicitly given as `No_Output_Operands`.
No support is provided for GNU C's symbolic names for output parameters.
The second argument of ``my_float'Asm_Output`` functions as
though it were an `out` parameter, which is a little curious, but
all names have the form of expressions, so there is no syntactic
irregularity, even though normally functions would not be permitted
`out` parameters. The third argument is the list of input
operands. It is either a single `Asm_Input` attribute reference, or
a list of such references enclosed in parentheses (technically an array
aggregate of such references).
The `Asm_Input` attribute denotes a function that takes two
parameters. The first is a string, the second is an expression of the
type designated by the prefix. The first (string) argument is required
to be a static expression, and is the constraint for the parameter,
(e.g., what kind of register is required). The second argument is the
value to be used as the input argument. The possible values for the
constraint are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
No support is provided for GNU C's symbolic names for input parameters.
If there are no input operands, this argument may either be omitted, or
explicitly given as `No_Input_Operands`. The fourth argument, not
present in the above example, is a list of register names, called the
*clobber* argument. This argument, if given, must be a static string
expression, and is a space or comma separated list of names of registers
that must be considered destroyed as a result of the `Asm` call. If
this argument is the null string (the default value), then the code
generator assumes that no additional registers are destroyed.
In addition to registers, the special clobbers `memory` and
`cc` as described in the GNU C docs are both supported.
The fifth argument, not present in the above example, called the
*volatile* argument, is by default `False`. It can be set to
the literal value `True` to indicate to the code generator that all
optimizations with respect to the instruction specified should be
suppressed, and in particular an instruction that has outputs
will still be generated, even if none of the outputs are
used. See :title:`Using_the_GNU_Compiler_Collection_(GCC)`
for the full description.
Generally it is strongly advisable to use Volatile for any ASM statement
that is missing either input or output operands or to avoid unwanted
optimizations. A warning is generated if this advice is not followed.
No support is provided for GNU C's `asm goto` feature.
The `Asm` subprograms may be used in two ways. First the procedure
forms can be used anywhere a procedure call would be valid, and
correspond to what the RM calls 'intrinsic' routines. Such calls can
be used to intersperse machine instructions with other Ada statements.
Second, the function forms, which return a dummy value of the limited
private type `Asm_Insn`, can be used in code statements, and indeed
this is the only context where such calls are allowed. Code statements
appear as aggregates of the form:
.. code-block:: ada
Asm_Insn'(Asm (...));
Asm_Insn'(Asm_Volatile (...));
In accordance with RM rules, such code statements are allowed only
within subprograms whose entire body consists of such statements. It is
not permissible to intermix such statements with other Ada statements.
Typically the form using intrinsic procedure calls is more convenient
and more flexible. The code statement form is provided to meet the RM
suggestion that such a facility should be made available. The following
is the exact syntax of the call to `Asm`. As usual, if named notation
is used, the arguments may be given in arbitrary order, following the
normal rules for use of positional and named arguments:
::
ASM_CALL ::= Asm (
[Template =>] static_string_EXPRESSION
[,[Outputs =>] OUTPUT_OPERAND_LIST ]
[,[Inputs =>] INPUT_OPERAND_LIST ]
[,[Clobber =>] static_string_EXPRESSION ]
[,[Volatile =>] static_boolean_EXPRESSION] )
OUTPUT_OPERAND_LIST ::=
[PREFIX.]No_Output_Operands
| OUTPUT_OPERAND_ATTRIBUTE
| (OUTPUT_OPERAND_ATTRIBUTE {,OUTPUT_OPERAND_ATTRIBUTE})
OUTPUT_OPERAND_ATTRIBUTE ::=
SUBTYPE_MARK'Asm_Output (static_string_EXPRESSION, NAME)
INPUT_OPERAND_LIST ::=
[PREFIX.]No_Input_Operands
| INPUT_OPERAND_ATTRIBUTE
| (INPUT_OPERAND_ATTRIBUTE {,INPUT_OPERAND_ATTRIBUTE})
INPUT_OPERAND_ATTRIBUTE ::=
SUBTYPE_MARK'Asm_Input (static_string_EXPRESSION, EXPRESSION)
The identifiers `No_Input_Operands` and `No_Output_Operands`
are declared in the package `Machine_Code` and must be referenced
according to normal visibility rules. In particular if there is no
`use` clause for this package, then appropriate package name
qualification is required.
.. _GNAT_Implementation_of_Tasking:
GNAT Implementation of Tasking
==============================
This chapter outlines the basic GNAT approach to tasking (in particular,
a multi-layered library for portability) and discusses issues related
to compliance with the Real-Time Systems Annex.
.. _Mapping_Ada_Tasks_onto_the_Underlying_Kernel_Threads:
Mapping Ada Tasks onto the Underlying Kernel Threads
----------------------------------------------------
GNAT's run-time support comprises two layers:
* GNARL (GNAT Run-time Layer)
* GNULL (GNAT Low-level Library)
In GNAT, Ada's tasking services rely on a platform and OS independent
layer known as GNARL. This code is responsible for implementing the
correct semantics of Ada's task creation, rendezvous, protected
operations etc.
GNARL decomposes Ada's tasking semantics into simpler lower level
operations such as create a thread, set the priority of a thread,
yield, create a lock, lock/unlock, etc. The spec for these low-level
operations constitutes GNULLI, the GNULL Interface. This interface is
directly inspired from the POSIX real-time API.
If the underlying executive or OS implements the POSIX standard
faithfully, the GNULL Interface maps as is to the services offered by
the underlying kernel. Otherwise, some target dependent glue code maps
the services offered by the underlying kernel to the semantics expected
by GNARL.
Whatever the underlying OS (VxWorks, UNIX, Windows, etc.) the
key point is that each Ada task is mapped on a thread in the underlying
kernel. For example, in the case of VxWorks, one Ada task = one VxWorks task.
In addition Ada task priorities map onto the underlying thread priorities.
Mapping Ada tasks onto the underlying kernel threads has several advantages:
*
The underlying scheduler is used to schedule the Ada tasks. This
makes Ada tasks as efficient as kernel threads from a scheduling
standpoint.
*
Interaction with code written in C containing threads is eased
since at the lowest level Ada tasks and C threads map onto the same
underlying kernel concept.
*
When an Ada task is blocked during I/O the remaining Ada tasks are
able to proceed.
*
On multiprocessor systems Ada tasks can execute in parallel.
Some threads libraries offer a mechanism to fork a new process, with the
child process duplicating the threads from the parent.
GNAT does not
support this functionality when the parent contains more than one task.
.. index:: Forking a new process
.. _Ensuring_Compliance_with_the_Real-Time_Annex:
Ensuring Compliance with the Real-Time Annex
--------------------------------------------
.. index:: Real-Time Systems Annex compliance
Although mapping Ada tasks onto
the underlying threads has significant advantages, it does create some
complications when it comes to respecting the scheduling semantics
specified in the real-time annex (Annex D).
For instance the Annex D requirement for the `FIFO_Within_Priorities`
scheduling policy states:
*When the active priority of a ready task that is not running
changes, or the setting of its base priority takes effect, the
task is removed from the ready queue for its old active priority
and is added at the tail of the ready queue for its new active
priority, except in the case where the active priority is lowered
due to the loss of inherited priority, in which case the task is
added at the head of the ready queue for its new active priority.*
While most kernels do put tasks at the end of the priority queue when
a task changes its priority, (which respects the main
FIFO_Within_Priorities requirement), almost none keep a thread at the
beginning of its priority queue when its priority drops from the loss
of inherited priority.
As a result most vendors have provided incomplete Annex D implementations.
The GNAT run-time, has a nice cooperative solution to this problem
which ensures that accurate FIFO_Within_Priorities semantics are
respected.
The principle is as follows. When an Ada task T is about to start
running, it checks whether some other Ada task R with the same
priority as T has been suspended due to the loss of priority
inheritance. If this is the case, T yields and is placed at the end of
its priority queue. When R arrives at the front of the queue it
executes.
Note that this simple scheme preserves the relative order of the tasks
that were ready to execute in the priority queue where R has been
placed at the end.
.. _GNAT_Implementation_of_Shared_Passive_Packages:
GNAT Implementation of Shared Passive Packages
==============================================
.. index:: Shared passive packages
GNAT fully implements the pragma `Shared_Passive` for
.. index:: pragma `Shared_Passive`
the purpose of designating shared passive packages.
This allows the use of passive partitions in the
context described in the Ada Reference Manual; i.e., for communication
between separate partitions of a distributed application using the
features in Annex E.
.. index:: Annex E
.. index:: Distribution Systems Annex
However, the implementation approach used by GNAT provides for more
extensive usage as follows:
*Communication between separate programs*
This allows separate programs to access the data in passive
partitions, using protected objects for synchronization where
needed. The only requirement is that the two programs have a
common shared file system. It is even possible for programs
running on different machines with different architectures
(e.g., different endianness) to communicate via the data in
a passive partition.
*Persistence between program runs*
The data in a passive package can persist from one run of a
program to another, so that a later program sees the final
values stored by a previous run of the same program.
The implementation approach used is to store the data in files. A
separate stream file is created for each object in the package, and
an access to an object causes the corresponding file to be read or
written.
.. index:: SHARED_MEMORY_DIRECTORY environment variable
The environment variable `SHARED_MEMORY_DIRECTORY` should be
set to the directory to be used for these files.
The files in this directory
have names that correspond to their fully qualified names. For
example, if we have the package
.. code-block:: ada
package X is
pragma Shared_Passive (X);
Y : Integer;
Z : Float;
end X;
and the environment variable is set to `/stemp/`, then the files created
will have the names:
::
/stemp/x.y
/stemp/x.z
These files are created when a value is initially written to the object, and
the files are retained until manually deleted. This provides the persistence
semantics. If no file exists, it means that no partition has assigned a value
to the variable; in this case the initial value declared in the package
will be used. This model ensures that there are no issues in synchronizing
the elaboration process, since elaboration of passive packages elaborates the
initial values, but does not create the files.
The files are written using normal `Stream_IO` access.
If you want to be able
to communicate between programs or partitions running on different
architectures, then you should use the XDR versions of the stream attribute
routines, since these are architecture independent.
If active synchronization is required for access to the variables in the
shared passive package, then as described in the Ada Reference Manual, the
package may contain protected objects used for this purpose. In this case
a lock file (whose name is :file:`___lock` (three underscores)
is created in the shared memory directory.
.. index:: ___lock file (for shared passive packages)
This is used to provide the required locking
semantics for proper protected object synchronization.
GNAT supports shared passive packages on all platforms
except for OpenVMS.
.. _Code_Generation_for_Array_Aggregates:
Code Generation for Array Aggregates
====================================
Aggregates have a rich syntax and allow the user to specify the values of
complex data structures by means of a single construct. As a result, the
code generated for aggregates can be quite complex and involve loops, case
statements and multiple assignments. In the simplest cases, however, the
compiler will recognize aggregates whose components and constraints are
fully static, and in those cases the compiler will generate little or no
executable code. The following is an outline of the code that GNAT generates
for various aggregate constructs. For further details, you will find it
useful to examine the output produced by the -gnatG flag to see the expanded
source that is input to the code generator. You may also want to examine
the assembly code generated at various levels of optimization.
The code generated for aggregates depends on the context, the component values,
and the type. In the context of an object declaration the code generated is
generally simpler than in the case of an assignment. As a general rule, static
component values and static subtypes also lead to simpler code.
.. _Static_constant_aggregates_with_static_bounds:
Static constant aggregates with static bounds
---------------------------------------------
For the declarations:
.. code-block:: ada
type One_Dim is array (1..10) of integer;
ar0 : constant One_Dim := (1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
GNAT generates no executable code: the constant ar0 is placed in static memory.
The same is true for constant aggregates with named associations:
.. code-block:: ada
Cr1 : constant One_Dim := (4 => 16, 2 => 4, 3 => 9, 1 => 1, 5 .. 10 => 0);
Cr3 : constant One_Dim := (others => 7777);
The same is true for multidimensional constant arrays such as:
.. code-block:: ada
type two_dim is array (1..3, 1..3) of integer;
Unit : constant two_dim := ( (1,0,0), (0,1,0), (0,0,1));
The same is true for arrays of one-dimensional arrays: the following are
static:
.. code-block:: ada
type ar1b is array (1..3) of boolean;
type ar_ar is array (1..3) of ar1b;
None : constant ar1b := (others => false); -- fully static
None2 : constant ar_ar := (1..3 => None); -- fully static
However, for multidimensional aggregates with named associations, GNAT will
generate assignments and loops, even if all associations are static. The
following two declarations generate a loop for the first dimension, and
individual component assignments for the second dimension:
.. code-block:: ada
Zero1: constant two_dim := (1..3 => (1..3 => 0));
Zero2: constant two_dim := (others => (others => 0));
.. _Constant_aggregates_with_unconstrained_nominal_types:
Constant aggregates with unconstrained nominal types
----------------------------------------------------
In such cases the aggregate itself establishes the subtype, so that
associations with `others` cannot be used. GNAT determines the
bounds for the actual subtype of the aggregate, and allocates the
aggregate statically as well. No code is generated for the following:
.. code-block:: ada
type One_Unc is array (natural range <>) of integer;
Cr_Unc : constant One_Unc := (12,24,36);
.. _Aggregates_with_static_bounds:
Aggregates with static bounds
-----------------------------
In all previous examples the aggregate was the initial (and immutable) value
of a constant. If the aggregate initializes a variable, then code is generated
for it as a combination of individual assignments and loops over the target
object. The declarations
.. code-block:: ada
Cr_Var1 : One_Dim := (2, 5, 7, 11, 0, 0, 0, 0, 0, 0);
Cr_Var2 : One_Dim := (others > -1);
generate the equivalent of
.. code-block:: ada
Cr_Var1 (1) := 2;
Cr_Var1 (2) := 3;
Cr_Var1 (3) := 5;
Cr_Var1 (4) := 11;
for I in Cr_Var2'range loop
Cr_Var2 (I) := -1;
end loop;
.. _Aggregates_with_non-static_bounds:
Aggregates with non-static bounds
---------------------------------
If the bounds of the aggregate are not statically compatible with the bounds
of the nominal subtype of the target, then constraint checks have to be
generated on the bounds. For a multidimensional array, constraint checks may
have to be applied to sub-arrays individually, if they do not have statically
compatible subtypes.
.. _Aggregates_in_assignment_statements:
Aggregates in assignment statements
-----------------------------------
In general, aggregate assignment requires the construction of a temporary,
and a copy from the temporary to the target of the assignment. This is because
it is not always possible to convert the assignment into a series of individual
component assignments. For example, consider the simple case:
.. code-block:: ada
A := (A(2), A(1));
This cannot be converted into:
.. code-block:: ada
A(1) := A(2);
A(2) := A(1);
So the aggregate has to be built first in a separate location, and then
copied into the target. GNAT recognizes simple cases where this intermediate
step is not required, and the assignments can be performed in place, directly
into the target. The following sufficient criteria are applied:
*
The bounds of the aggregate are static, and the associations are static.
*
The components of the aggregate are static constants, names of
simple variables that are not renamings, or expressions not involving
indexed components whose operands obey these rules.
If any of these conditions are violated, the aggregate will be built in
a temporary (created either by the front-end or the code generator) and then
that temporary will be copied onto the target.
.. _The_Size_of_Discriminated_Records_with_Default_Discriminants:
The Size of Discriminated Records with Default Discriminants
============================================================
If a discriminated type `T` has discriminants with default values, it is
possible to declare an object of this type without providing an explicit
constraint:
.. code-block:: ada
type Size is range 1..100;
type Rec (D : Size := 15) is record
Name : String (1..D);
end T;
Word : Rec;
Such an object is said to be *unconstrained*.
The discriminant of the object
can be modified by a full assignment to the object, as long as it preserves the
relation between the value of the discriminant, and the value of the components
that depend on it:
.. code-block:: ada
Word := (3, "yes");
Word := (5, "maybe");
Word := (5, "no"); -- raises Constraint_Error
In order to support this behavior efficiently, an unconstrained object is
given the maximum size that any value of the type requires. In the case
above, `Word` has storage for the discriminant and for
a `String` of length 100.
It is important to note that unconstrained objects do not require dynamic
allocation. It would be an improper implementation to place on the heap those
components whose size depends on discriminants. (This improper implementation
was used by some Ada83 compilers, where the `Name` component above
would have
been stored as a pointer to a dynamic string). Following the principle that
dynamic storage management should never be introduced implicitly,
an Ada compiler should reserve the full size for an unconstrained declared
object, and place it on the stack.
This maximum size approach
has been a source of surprise to some users, who expect the default
values of the discriminants to determine the size reserved for an
unconstrained object: "If the default is 15, why should the object occupy
a larger size?"
The answer, of course, is that the discriminant may be later modified,
and its full range of values must be taken into account. This is why the
declaration:
.. code-block:: ada
type Rec (D : Positive := 15) is record
Name : String (1..D);
end record;
Too_Large : Rec;
is flagged by the compiler with a warning:
an attempt to create `Too_Large` will raise `Storage_Error`,
because the required size includes `Positive'Last`
bytes. As the first example indicates, the proper approach is to declare an
index type of 'reasonable' range so that unconstrained objects are not too
large.
One final wrinkle: if the object is declared to be `aliased`, or if it is
created in the heap by means of an allocator, then it is *not*
unconstrained:
it is constrained by the default values of the discriminants, and those values
cannot be modified by full assignment. This is because in the presence of
aliasing all views of the object (which may be manipulated by different tasks,
say) must be consistent, so it is imperative that the object, once created,
remain invariant.
.. _Strict_Conformance_to_the_Ada_Reference_Manual:
Strict Conformance to the Ada Reference Manual
==============================================
The dynamic semantics defined by the Ada Reference Manual impose a set of
run-time checks to be generated. By default, the GNAT compiler will insert many
run-time checks into the compiled code, including most of those required by the
Ada Reference Manual. However, there are three checks that are not enabled
in the default mode for efficiency reasons: arithmetic overflow checking for
integer operations (including division by zero), checks for access before
elaboration on subprogram calls, and stack overflow checking (most operating
systems do not perform this check by default).
Strict conformance to the Ada Reference Manual can be achieved by adding
three compiler options for overflow checking for integer operations
(*-gnato*), dynamic checks for access-before-elaboration on subprogram
calls and generic instantiations (*-gnatE*), and stack overflow
checking (*-fstack-check*).
Note that the result of a floating point arithmetic operation in overflow and
invalid situations, when the `Machine_Overflows` attribute of the result
type is `False`, is to generate IEEE NaN and infinite values. This is the
case for machines compliant with the IEEE floating-point standard, but on
machines that are not fully compliant with this standard, such as Alpha, the
*-mieee* compiler flag must be used for achieving IEEE confirming
behavior (although at the cost of a significant performance penalty), so
infinite and NaN values are properly generated.
.. _Interfacing_to_Other_Languages:
******************************
Interfacing to Other Languages
******************************
The facilities in Annex B of the Ada Reference Manual are fully
implemented in GNAT, and in addition, a full interface to C++ is
provided.
.. _Interfacing_to_C:
Interfacing to C
================
Interfacing to C with GNAT can use one of two approaches:
*
The types in the package `Interfaces.C` may be used.
*
Standard Ada types may be used directly. This may be less portable to
other compilers, but will work on all GNAT compilers, which guarantee
correspondence between the C and Ada types.
Pragma `Convention C` may be applied to Ada types, but mostly has no
effect, since this is the default. The following table shows the
correspondence between Ada scalar types and the corresponding C types.
======================== ==================================================================
Ada Type C Type
======================== ==================================================================
``Integer`` ``int``
``Short_Integer`` ``short``
``Short_Short_Integer`` ``signed char``
``Long_Integer`` ``long``
``Long_Long_Integer`` ``long long``
``Short_Float`` ``float``
``Float`` ``float``
``Long_Float`` ``double``
``Long_Long_Float`` This is the longest floating-point type supported by the hardware.
======================== ==================================================================
Additionally, there are the following general correspondences between Ada
and C types:
*
Ada enumeration types map to C enumeration types directly if pragma
`Convention C` is specified, which causes them to have int
length. Without pragma `Convention C`, Ada enumeration types map to
8, 16, or 32 bits (i.e., C types `signed char`, `short`,
`int`, respectively) depending on the number of values passed.
This is the only case in which pragma `Convention C` affects the
representation of an Ada type.
*
Ada access types map to C pointers, except for the case of pointers to
unconstrained types in Ada, which have no direct C equivalent.
*
Ada arrays map directly to C arrays.
*
Ada records map directly to C structures.
*
Packed Ada records map to C structures where all members are bit fields
of the length corresponding to the ``type'Size`` value in Ada.
.. _Interfacing_to_C++:
Interfacing to C++
==================
The interface to C++ makes use of the following pragmas, which are
primarily intended to be constructed automatically using a binding generator
tool, although it is possible to construct them by hand.
Using these pragmas it is possible to achieve complete
inter-operability between Ada tagged types and C++ class definitions.
See :ref:`Implementation_Defined_Pragmas`, for more details.
*pragma CPP_Class ([Entity =>] `LOCAL_NAME`)*
The argument denotes an entity in the current declarative region that is
declared as a tagged or untagged record type. It indicates that the type
corresponds to an externally declared C++ class type, and is to be laid
out the same way that C++ would lay out the type.
Note: Pragma `CPP_Class` is currently obsolete. It is supported
for backward compatibility but its functionality is available
using pragma `Import` with `Convention` = `CPP`.
*pragma CPP_Constructor ([Entity =>] `LOCAL_NAME`)*
This pragma identifies an imported function (imported in the usual way
with pragma `Import`) as corresponding to a C++ constructor.
A few restrictions are placed on the use of the `Access` attribute
in conjunction with subprograms subject to convention `CPP`: the
attribute may be used neither on primitive operations of a tagged
record type with convention `CPP`, imported or not, nor on
subprograms imported with pragma `CPP_Constructor`.
In addition, C++ exceptions are propagated and can be handled in an
`others` choice of an exception handler. The corresponding Ada
occurrence has no message, and the simple name of the exception identity
contains ``Foreign_Exception``. Finalization and awaiting dependent
tasks works properly when such foreign exceptions are propagated.
It is also possible to import a C++ exception using the following syntax:
::
LOCAL_NAME : exception;
pragma Import (Cpp,
[Entity =>] LOCAL_NAME,
[External_Name =>] static_string_EXPRESSION);
The `External_Name` is the name of the C++ RTTI symbol. You can then
cover a specific C++ exception in an exception handler.
.. _Interfacing_to_COBOL:
Interfacing to COBOL
====================
Interfacing to COBOL is achieved as described in section B.4 of
the Ada Reference Manual.
.. _Interfacing_to_Fortran:
Interfacing to Fortran
======================
Interfacing to Fortran is achieved as described in section B.5 of the
Ada Reference Manual. The pragma `Convention Fortran`, applied to a
multi-dimensional array causes the array to be stored in column-major
order as required for convenient interface to Fortran.
.. _Interfacing_to_non-GNAT_Ada_code:
Interfacing to non-GNAT Ada code
================================
It is possible to specify the convention `Ada` in a pragma
`Import` or pragma `Export`. However this refers to
the calling conventions used by GNAT, which may or may not be
similar enough to those used by some other Ada 83 / Ada 95 / Ada 2005
compiler to allow interoperation.
If arguments types are kept simple, and if the foreign compiler generally
follows system calling conventions, then it may be possible to integrate
files compiled by other Ada compilers, provided that the elaboration
issues are adequately addressed (for example by eliminating the
need for any load time elaboration).
In particular, GNAT running on VMS is designed to
be highly compatible with the DEC Ada 83 compiler, so this is one
case in which it is possible to import foreign units of this type,
provided that the data items passed are restricted to simple scalar
values or simple record types without variants, or simple array
types with fixed bounds.
.. _Intrinsic_Subprograms:
*********************
Intrinsic Subprograms
*********************
.. index:: Intrinsic Subprograms
GNAT allows a user application program to write the declaration:
.. code-block:: ada
pragma Import (Intrinsic, name);
providing that the name corresponds to one of the implemented intrinsic
subprograms in GNAT, and that the parameter profile of the referenced
subprogram meets the requirements. This chapter describes the set of
implemented intrinsic subprograms, and the requirements on parameter profiles.
Note that no body is supplied; as with other uses of pragma Import, the
body is supplied elsewhere (in this case by the compiler itself). Note
that any use of this feature is potentially non-portable, since the
Ada standard does not require Ada compilers to implement this feature.
.. _Intrinsic_Operators:
Intrinsic Operators
===================
.. index:: Intrinsic operator
All the predefined numeric operators in package Standard
in `pragma Import (Intrinsic,..)`
declarations. In the binary operator case, the operands must have the same
size. The operand or operands must also be appropriate for
the operator. For example, for addition, the operands must
both be floating-point or both be fixed-point, and the
right operand for `"**"` must have a root type of
`Standard.Integer'Base`.
You can use an intrinsic operator declaration as in the following example:
.. code-block:: ada
type Int1 is new Integer;
type Int2 is new Integer;
function "+" (X1 : Int1; X2 : Int2) return Int1;
function "+" (X1 : Int1; X2 : Int2) return Int2;
pragma Import (Intrinsic, "+");
This declaration would permit 'mixed mode' arithmetic on items
of the differing types `Int1` and `Int2`.
It is also possible to specify such operators for private types, if the
full views are appropriate arithmetic types.
.. _Compilation_Date:
Compilation_Date
================
.. index:: Compilation_Date
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.Compilation_Date` to obtain the date of
the current compilation (in local time format MMM DD YYYY).
.. _Compilation_Time:
Compilation_Time
================
.. index:: Compilation_Time
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.Compilation_Time` to obtain the time of
the current compilation (in local time format HH:MM:SS).
.. _Enclosing_Entity:
Enclosing_Entity
================
.. index:: Enclosing_Entity
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.Enclosing_Entity` to obtain the name of
the current subprogram, package, task, entry, or protected subprogram.
.. _Exception_Information:
Exception_Information
=====================
.. index:: Exception_Information'
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Current_Exception`. The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
`GNAT.Current_Exception.Exception_Information` to obtain
the exception information associated with the current exception.
.. _Exception_Message:
Exception_Message
=================
.. index:: Exception_Message
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Current_Exception`. The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
`GNAT.Current_Exception.Exception_Message` to obtain
the message associated with the current exception.
.. _Exception_Name:
Exception_Name
==============
.. index:: Exception_Name
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Current_Exception`. The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
`GNAT.Current_Exception.Exception_Name` to obtain
the name of the current exception.
.. _File:
File
====
.. index:: File
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.File` to obtain the name of the current
file.
.. _Line:
Line
====
.. index:: Line
This intrinsic subprogram is used in the implementation of the
library package `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.Line` to obtain the number of the current
source line.
.. _Shifts_and_Rotates:
Shifts and Rotates
==================
.. index:: Shift_Left
.. index:: Shift_Right
.. index:: Shift_Right_Arithmetic
.. index:: Rotate_Left
.. index:: Rotate_Right
In standard Ada, the shift and rotate functions are available only
for the predefined modular types in package `Interfaces`. However, in
GNAT it is possible to define these functions for any integer
type (signed or modular), as in this example:
.. code-block:: ada
function Shift_Left
(Value : T;
Amount : Natural) return T;
The function name must be one of
Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, or
Rotate_Right. T must be an integer type. T'Size must be
8, 16, 32 or 64 bits; if T is modular, the modulus
must be 2**8, 2**16, 2**32 or 2**64.
The result type must be the same as the type of `Value`.
The shift amount must be Natural.
The formal parameter names can be anything.
A more convenient way of providing these shift operators is to use
the Provide_Shift_Operators pragma, which provides the function declarations
and corresponding pragma Import's for all five shift functions.
.. _Source_Location:
Source_Location
===============
.. index:: Source_Location
This intrinsic subprogram is used in the implementation of the
library routine `GNAT.Source_Info`. The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
`GNAT.Source_Info.Source_Location` to obtain the current
source file location.
.. _Obsolescent_Features:
********************
Obsolescent Features
********************
This chapter describes features that are provided by GNAT, but are
considered obsolescent since there are preferred ways of achieving
the same effect. These features are provided solely for historical
compatibility purposes.
.. _pragma_No_Run_Time:
pragma No_Run_Time
==================
The pragma `No_Run_Time` is used to achieve an affect similar
to the use of the "Zero Foot Print" configurable run time, but without
requiring a specially configured run time. The result of using this
pragma, which must be used for all units in a partition, is to restrict
the use of any language features requiring run-time support code. The
preferred usage is to use an appropriately configured run-time that
includes just those features that are to be made accessible.
.. _pragma_Ravenscar:
pragma Ravenscar
================
The pragma `Ravenscar` has exactly the same effect as pragma
`Profile (Ravenscar)`. The latter usage is preferred since it
is part of the new Ada 2005 standard.
.. _pragma_Restricted_Run_Time:
pragma Restricted_Run_Time
==========================
The pragma `Restricted_Run_Time` has exactly the same effect as
pragma `Profile (Restricted)`. The latter usage is
preferred since the Ada 2005 pragma `Profile` is intended for
this kind of implementation dependent addition.
.. _pragma_Task_Info:
pragma Task_Info
================
The functionality provided by pragma `Task_Info` is now part of the
Ada language. The `CPU` aspect and the package
`System.Multiprocessors` offer a less system-dependent way to specify
task affinity or to query the number of processsors.
Syntax
.. code-block:: ada
pragma Task_Info (EXPRESSION);
This pragma appears within a task definition (like pragma
`Priority`) and applies to the task in which it appears. The
argument must be of type `System.Task_Info.Task_Info_Type`.
The `Task_Info` pragma provides system dependent control over
aspects of tasking implementation, for example, the ability to map
tasks to specific processors. For details on the facilities available
for the version of GNAT that you are using, see the documentation
in the spec of package System.Task_Info in the runtime
library.
.. _package_System_Task_Info:
package System.Task_Info (:file:`s-tasinf.ads`)
===============================================
This package provides target dependent functionality that is used
to support the `Task_Info` pragma. The predefined Ada package
`System.Multiprocessors` and the `CPU` aspect now provide a
standard replacement for GNAT's `Task_Info` functionality.
.. raw:: latex
\appendix
.. _Representation_Clauses_and_Pragmas:
**********************************
Representation Clauses and Pragmas
**********************************
.. index:: Representation Clauses
.. index:: Representation Clause
.. index:: Representation Pragma
.. index:: Pragma, representation
This section describes the representation clauses accepted by GNAT, and
their effect on the representation of corresponding data objects.
GNAT fully implements Annex C (Systems Programming). This means that all
the implementation advice sections in chapter 13 are fully implemented.
However, these sections only require a minimal level of support for
representation clauses. GNAT provides much more extensive capabilities,
and this section describes the additional capabilities provided.
.. _Alignment_Clauses:
Alignment Clauses
=================
.. index:: Alignment Clause
GNAT requires that all alignment clauses specify a power of 2, and all
default alignments are always a power of 2. The default alignment
values are as follows:
* *Primitive Types*.
For primitive types, the alignment is the minimum of the actual size of
objects of the type divided by `Storage_Unit`,
and the maximum alignment supported by the target.
(This maximum alignment is given by the GNAT-specific attribute
`Standard'Maximum_Alignment`; see :ref:`Attribute_Maximum_Alignment`.)
.. index:: Maximum_Alignment attribute
For example, for type `Long_Float`, the object size is 8 bytes, and the
default alignment will be 8 on any target that supports alignments
this large, but on some targets, the maximum alignment may be smaller
than 8, in which case objects of type `Long_Float` will be maximally
aligned.
* *Arrays*.
For arrays, the alignment is equal to the alignment of the component type
for the normal case where no packing or component size is given. If the
array is packed, and the packing is effective (see separate section on
packed arrays), then the alignment will be one for long packed arrays,
or arrays whose length is not known at compile time. For short packed
arrays, which are handled internally as modular types, the alignment
will be as described for primitive types, e.g., a packed array of length
31 bits will have an object size of four bytes, and an alignment of 4.
* *Records*.
For the normal non-packed case, the alignment of a record is equal to
the maximum alignment of any of its components. For tagged records, this
includes the implicit access type used for the tag. If a pragma `Pack`
is used and all components are packable (see separate section on pragma
`Pack`), then the resulting alignment is 1, unless the layout of the
record makes it profitable to increase it.
A special case is when:
* the size of the record is given explicitly, or a
full record representation clause is given, and
* the size of the record is 2, 4, or 8 bytes.
In this case, an alignment is chosen to match the
size of the record. For example, if we have:
.. code-block:: ada
type Small is record
A, B : Character;
end record;
for Small'Size use 16;
then the default alignment of the record type `Small` is 2, not 1. This
leads to more efficient code when the record is treated as a unit, and also
allows the type to specified as `Atomic` on architectures requiring
strict alignment.
An alignment clause may specify a larger alignment than the default value
up to some maximum value dependent on the target (obtainable by using the
attribute reference `Standard'Maximum_Alignment`). It may also specify
a smaller alignment than the default value for enumeration, integer and
fixed point types, as well as for record types, for example
.. code-block:: ada
type V is record
A : Integer;
end record;
for V'alignment use 1;
.. index:: Alignment, default
The default alignment for the type `V` is 4, as a result of the
Integer field in the record, but it is permissible, as shown, to
override the default alignment of the record with a smaller value.
.. index:: Alignment, subtypes
Note that according to the Ada standard, an alignment clause applies only
to the first named subtype. If additional subtypes are declared, then the
compiler is allowed to choose any alignment it likes, and there is no way
to control this choice. Consider:
.. code-block:: ada
type R is range 1 .. 10_000;
for R'Alignment use 1;
subtype RS is R range 1 .. 1000;
The alignment clause specifies an alignment of 1 for the first named subtype
`R` but this does not necessarily apply to `RS`. When writing
portable Ada code, you should avoid writing code that explicitly or
implicitly relies on the alignment of such subtypes.
For the GNAT compiler, if an explicit alignment clause is given, this
value is also used for any subsequent subtypes. So for GNAT, in the
above example, you can count on the alignment of `RS` being 1. But this
assumption is non-portable, and other compilers may choose different
alignments for the subtype `RS`.
.. _Size_Clauses:
Size Clauses
============
.. index:: Size Clause
The default size for a type `T` is obtainable through the
language-defined attribute `T'Size` and also through the
equivalent GNAT-defined attribute `T'Value_Size`.
For objects of type `T`, GNAT will generally increase the type size
so that the object size (obtainable through the GNAT-defined attribute
`T'Object_Size`)
is a multiple of `T'Alignment * Storage_Unit`.
For example:
.. code-block:: ada
type Smallint is range 1 .. 6;
type Rec is record
Y1 : integer;
Y2 : boolean;
end record;
In this example, `Smallint'Size` = `Smallint'Value_Size` = 3,
as specified by the RM rules,
but objects of this type will have a size of 8
(`Smallint'Object_Size` = 8),
since objects by default occupy an integral number
of storage units. On some targets, notably older
versions of the Digital Alpha, the size of stand
alone objects of this type may be 32, reflecting
the inability of the hardware to do byte load/stores.
Similarly, the size of type `Rec` is 40 bits
(`Rec'Size` = `Rec'Value_Size` = 40), but
the alignment is 4, so objects of this type will have
their size increased to 64 bits so that it is a multiple
of the alignment (in bits). This decision is
in accordance with the specific Implementation Advice in RM 13.3(43):
"A `Size` clause should be supported for an object if the specified
`Size` is at least as large as its subtype's `Size`, and corresponds
to a size in storage elements that is a multiple of the object's
`Alignment` (if the `Alignment` is nonzero)."
An explicit size clause may be used to override the default size by
increasing it. For example, if we have:
.. code-block:: ada
type My_Boolean is new Boolean;
for My_Boolean'Size use 32;
then values of this type will always be 32 bits long. In the case of
discrete types, the size can be increased up to 64 bits, with the effect
that the entire specified field is used to hold the value, sign- or
zero-extended as appropriate. If more than 64 bits is specified, then
padding space is allocated after the value, and a warning is issued that
there are unused bits.
Similarly the size of records and arrays may be increased, and the effect
is to add padding bits after the value. This also causes a warning message
to be generated.
The largest Size value permitted in GNAT is 2**31-1. Since this is a
Size in bits, this corresponds to an object of size 256 megabytes (minus
one). This limitation is true on all targets. The reason for this
limitation is that it improves the quality of the code in many cases
if it is known that a Size value can be accommodated in an object of
type Integer.
.. _Storage_Size_Clauses:
Storage_Size Clauses
====================
.. index:: Storage_Size Clause
For tasks, the `Storage_Size` clause specifies the amount of space
to be allocated for the task stack. This cannot be extended, and if the
stack is exhausted, then `Storage_Error` will be raised (if stack
checking is enabled). Use a `Storage_Size` attribute definition clause,
or a `Storage_Size` pragma in the task definition to set the
appropriate required size. A useful technique is to include in every
task definition a pragma of the form:
.. code-block:: ada
pragma Storage_Size (Default_Stack_Size);
Then `Default_Stack_Size` can be defined in a global package, and
modified as required. Any tasks requiring stack sizes different from the
default can have an appropriate alternative reference in the pragma.
You can also use the *-d* binder switch to modify the default stack
size.
For access types, the `Storage_Size` clause specifies the maximum
space available for allocation of objects of the type. If this space is
exceeded then `Storage_Error` will be raised by an allocation attempt.
In the case where the access type is declared local to a subprogram, the
use of a `Storage_Size` clause triggers automatic use of a special
predefined storage pool (`System.Pool_Size`) that ensures that all
space for the pool is automatically reclaimed on exit from the scope in
which the type is declared.
A special case recognized by the compiler is the specification of a
`Storage_Size` of zero for an access type. This means that no
items can be allocated from the pool, and this is recognized at compile
time, and all the overhead normally associated with maintaining a fixed
size storage pool is eliminated. Consider the following example:
.. code-block:: ada
procedure p is
type R is array (Natural) of Character;
type P is access all R;
for P'Storage_Size use 0;
-- Above access type intended only for interfacing purposes
y : P;
procedure g (m : P);
pragma Import (C, g);
-- ...
begin
-- ...
y := new R;
end;
As indicated in this example, these dummy storage pools are often useful in
connection with interfacing where no object will ever be allocated. If you
compile the above example, you get the warning:
::
p.adb:16:09: warning: allocation from empty storage pool
p.adb:16:09: warning: Storage_Error will be raised at run time
Of course in practice, there will not be any explicit allocators in the
case of such an access declaration.
.. _Size_of_Variant_Record_Objects:
Size of Variant Record Objects
==============================
.. index:: Size, variant record objects
.. index:: Variant record objects, size
In the case of variant record objects, there is a question whether Size gives
information about a particular variant, or the maximum size required
for any variant. Consider the following program
.. code-block:: ada
with Text_IO; use Text_IO;
procedure q is
type R1 (A : Boolean := False) is record
case A is
when True => X : Character;
when False => null;
end case;
end record;
V1 : R1 (False);
V2 : R1;
begin
Put_Line (Integer'Image (V1'Size));
Put_Line (Integer'Image (V2'Size));
end q;
Here we are dealing with a variant record, where the True variant
requires 16 bits, and the False variant requires 8 bits.
In the above example, both V1 and V2 contain the False variant,
which is only 8 bits long. However, the result of running the
program is:
::
8
16
The reason for the difference here is that the discriminant value of
V1 is fixed, and will always be False. It is not possible to assign
a True variant value to V1, therefore 8 bits is sufficient. On the
other hand, in the case of V2, the initial discriminant value is
False (from the default), but it is possible to assign a True
variant value to V2, therefore 16 bits must be allocated for V2
in the general case, even fewer bits may be needed at any particular
point during the program execution.
As can be seen from the output of this program, the `'Size`
attribute applied to such an object in GNAT gives the actual allocated
size of the variable, which is the largest size of any of the variants.
The Ada Reference Manual is not completely clear on what choice should
be made here, but the GNAT behavior seems most consistent with the
language in the RM.
In some cases, it may be desirable to obtain the size of the current
variant, rather than the size of the largest variant. This can be
achieved in GNAT by making use of the fact that in the case of a
subprogram parameter, GNAT does indeed return the size of the current
variant (because a subprogram has no way of knowing how much space
is actually allocated for the actual).
Consider the following modified version of the above program:
.. code-block:: ada
with Text_IO; use Text_IO;
procedure q is
type R1 (A : Boolean := False) is record
case A is
when True => X : Character;
when False => null;
end case;
end record;
V2 : R1;
function Size (V : R1) return Integer is
begin
return V'Size;
end Size;
begin
Put_Line (Integer'Image (V2'Size));
Put_Line (Integer'IMage (Size (V2)));
V2 := (True, 'x');
Put_Line (Integer'Image (V2'Size));
Put_Line (Integer'IMage (Size (V2)));
end q;
The output from this program is
::
16
8
16
16
Here we see that while the `'Size` attribute always returns
the maximum size, regardless of the current variant value, the
`Size` function does indeed return the size of the current
variant value.
.. _Biased_Representation:
Biased Representation
=====================
.. index:: Size for biased representation
.. index:: Biased representation
In the case of scalars with a range starting at other than zero, it is
possible in some cases to specify a size smaller than the default minimum
value, and in such cases, GNAT uses an unsigned biased representation,
in which zero is used to represent the lower bound, and successive values
represent successive values of the type.
For example, suppose we have the declaration:
.. code-block:: ada
type Small is range -7 .. -4;
for Small'Size use 2;
Although the default size of type `Small` is 4, the `Size`
clause is accepted by GNAT and results in the following representation
scheme:
::
-7 is represented as 2#00#
-6 is represented as 2#01#
-5 is represented as 2#10#
-4 is represented as 2#11#
Biased representation is only used if the specified `Size` clause
cannot be accepted in any other manner. These reduced sizes that force
biased representation can be used for all discrete types except for
enumeration types for which a representation clause is given.
.. _Value_Size_and_Object_Size_Clauses:
Value_Size and Object_Size Clauses
==================================
.. index:: Value_Size
.. index:: Object_Size
.. index:: Size, of objects
In Ada 95 and Ada 2005, `T'Size` for a type `T` is the minimum
number of bits required to hold values of type `T`.
Although this interpretation was allowed in Ada 83, it was not required,
and this requirement in practice can cause some significant difficulties.
For example, in most Ada 83 compilers, `Natural'Size` was 32.
However, in Ada 95 and Ada 2005,
`Natural'Size` is
typically 31. This means that code may change in behavior when moving
from Ada 83 to Ada 95 or Ada 2005. For example, consider:
.. code-block:: ada
type Rec is record;
A : Natural;
B : Natural;
end record;
for Rec use record
at 0 range 0 .. Natural'Size - 1;
at 0 range Natural'Size .. 2 * Natural'Size - 1;
end record;
In the above code, since the typical size of `Natural` objects
is 32 bits and `Natural'Size` is 31, the above code can cause
unexpected inefficient packing in Ada 95 and Ada 2005, and in general
there are cases where the fact that the object size can exceed the
size of the type causes surprises.
To help get around this problem GNAT provides two implementation
defined attributes, `Value_Size` and `Object_Size`. When
applied to a type, these attributes yield the size of the type
(corresponding to the RM defined size attribute), and the size of
objects of the type respectively.
The `Object_Size` is used for determining the default size of
objects and components. This size value can be referred to using the
`Object_Size` attribute. The phrase 'is used' here means that it is
the basis of the determination of the size. The backend is free to
pad this up if necessary for efficiency, e.g., an 8-bit stand-alone
character might be stored in 32 bits on a machine with no efficient
byte access instructions such as the Alpha.
The default rules for the value of `Object_Size` for
discrete types are as follows:
*
The `Object_Size` for base subtypes reflect the natural hardware
size in bits (run the compiler with *-gnatS* to find those values
for numeric types). Enumeration types and fixed-point base subtypes have
8, 16, 32 or 64 bits for this size, depending on the range of values
to be stored.
*
The `Object_Size` of a subtype is the same as the
`Object_Size` of
the type from which it is obtained.
*
The `Object_Size` of a derived base type is copied from the parent
base type, and the `Object_Size` of a derived first subtype is copied
from the parent first subtype.
The `Value_Size` attribute
is the (minimum) number of bits required to store a value
of the type.
This value is used to determine how tightly to pack
records or arrays with components of this type, and also affects
the semantics of unchecked conversion (unchecked conversions where
the `Value_Size` values differ generate a warning, and are potentially
target dependent).
The default rules for the value of `Value_Size` are as follows:
*
The `Value_Size` for a base subtype is the minimum number of bits
required to store all values of the type (including the sign bit
only if negative values are possible).
*
If a subtype statically matches the first subtype of a given type, then it has
by default the same `Value_Size` as the first subtype. This is a
consequence of RM 13.1(14): "if two subtypes statically match,
then their subtype-specific aspects are the same".)
*
All other subtypes have a `Value_Size` corresponding to the minimum
number of bits required to store all values of the subtype. For
dynamic bounds, it is assumed that the value can range down or up
to the corresponding bound of the ancestor
The RM defined attribute `Size` corresponds to the
`Value_Size` attribute.
The `Size` attribute may be defined for a first-named subtype. This sets
the `Value_Size` of
the first-named subtype to the given value, and the
`Object_Size` of this first-named subtype to the given value padded up
to an appropriate boundary. It is a consequence of the default rules
above that this `Object_Size` will apply to all further subtypes. On the
other hand, `Value_Size` is affected only for the first subtype, any
dynamic subtypes obtained from it directly, and any statically matching
subtypes. The `Value_Size` of any other static subtypes is not affected.
`Value_Size` and
`Object_Size` may be explicitly set for any subtype using
an attribute definition clause. Note that the use of these attributes
can cause the RM 13.1(14) rule to be violated. If two access types
reference aliased objects whose subtypes have differing `Object_Size`
values as a result of explicit attribute definition clauses, then it
is illegal to convert from one access subtype to the other. For a more
complete description of this additional legality rule, see the
description of the `Object_Size` attribute.
At the implementation level, Esize stores the Object_Size and the
RM_Size field stores the `Value_Size` (and hence the value of the
`Size` attribute,
which, as noted above, is equivalent to `Value_Size`).
To get a feel for the difference, consider the following examples (note
that in each case the base is `Short_Short_Integer` with a size of 8):
+---------------------------------------------+-------------+-------------+
|Type or subtype declaration | Object_Size | Value_Size|
+=============================================+=============+=============+
|``type x1 is range 0 .. 5;`` | 8 | 3 |
+---------------------------------------------+-------------+-------------+
|``type x2 is range 0 .. 5;`` | 16 | 12 |
|``for x2'size use 12;`` | | |
+---------------------------------------------+-------------+-------------+
|``subtype x3 is x2 range 0 .. 3;`` | 16 | 2 |
+---------------------------------------------+-------------+-------------+
|``subtype x4 is x2'base range 0 .. 10;`` | 8 | 4 |
+---------------------------------------------+-------------+-------------+
|``subtype x5 is x2 range 0 .. dynamic;`` | 16 | 3* |
+---------------------------------------------+-------------+-------------+
|``subtype x6 is x2'base range 0 .. dynamic;``| 8 | 3* |
+---------------------------------------------+-------------+-------------+
Note: the entries marked '3*' are not actually specified by the Ada
Reference Manual, but it seems in the spirit of the RM rules to allocate
the minimum number of bits (here 3, given the range for `x2`)
known to be large enough to hold the given range of values.
So far, so good, but GNAT has to obey the RM rules, so the question is
under what conditions must the RM `Size` be used.
The following is a list
of the occasions on which the RM `Size` must be used:
*
Component size for packed arrays or records
*
Value of the attribute `Size` for a type
*
Warning about sizes not matching for unchecked conversion
For record types, the `Object_Size` is always a multiple of the
alignment of the type (this is true for all types). In some cases the
`Value_Size` can be smaller. Consider:
.. code-block:: ada
type R is record
X : Integer;
Y : Character;
end record;
On a typical 32-bit architecture, the X component will be four bytes, and
require four-byte alignment, and the Y component will be one byte. In this
case `R'Value_Size` will be 40 (bits) since this is the minimum size
required to store a value of this type, and for example, it is permissible
to have a component of type R in an outer array whose component size is
specified to be 48 bits. However, `R'Object_Size` will be 64 (bits),
since it must be rounded up so that this value is a multiple of the
alignment (4 bytes = 32 bits).
For all other types, the `Object_Size`
and Value_Size are the same (and equivalent to the RM attribute `Size`).
Only `Size` may be specified for such types.
Note that `Value_Size` can be used to force biased representation
for a particular subtype. Consider this example:
.. code-block:: ada
type R is (A, B, C, D, E, F);
subtype RAB is R range A .. B;
subtype REF is R range E .. F;
By default, `RAB`
has a size of 1 (sufficient to accommodate the representation
of `A` and `B`, 0 and 1), and `REF`
has a size of 3 (sufficient to accommodate the representation
of `E` and `F`, 4 and 5). But if we add the
following `Value_Size` attribute definition clause:
.. code-block:: ada
for REF'Value_Size use 1;
then biased representation is forced for `REF`,
and 0 will represent `E` and 1 will represent `F`.
A warning is issued when a `Value_Size` attribute
definition clause forces biased representation. This
warning can be turned off using `-gnatw.B`.
.. _Component_Size_Clauses:
Component_Size Clauses
======================
.. index:: Component_Size Clause
Normally, the value specified in a component size clause must be consistent
with the subtype of the array component with regard to size and alignment.
In other words, the value specified must be at least equal to the size
of this subtype, and must be a multiple of the alignment value.
In addition, component size clauses are allowed which cause the array
to be packed, by specifying a smaller value. A first case is for
component size values in the range 1 through 63. The value specified
must not be smaller than the Size of the subtype. GNAT will accurately
honor all packing requests in this range. For example, if we have:
.. code-block:: ada
type r is array (1 .. 8) of Natural;
for r'Component_Size use 31;
then the resulting array has a length of 31 bytes (248 bits = 8 * 31).
Of course access to the components of such an array is considerably
less efficient than if the natural component size of 32 is used.
A second case is when the subtype of the component is a record type
padded because of its default alignment. For example, if we have:
.. code-block:: ada
type r is record
i : Integer;
j : Integer;
b : Boolean;
end record;
type a is array (1 .. 8) of r;
for a'Component_Size use 72;
then the resulting array has a length of 72 bytes, instead of 96 bytes
if the alignment of the record (4) was obeyed.
Note that there is no point in giving both a component size clause
and a pragma Pack for the same array type. if such duplicate
clauses are given, the pragma Pack will be ignored.
.. _Bit_Order_Clauses:
Bit_Order Clauses
=================
.. index:: Bit_Order Clause
.. index:: bit ordering
.. index:: ordering, of bits
For record subtypes, GNAT permits the specification of the `Bit_Order`
attribute. The specification may either correspond to the default bit
order for the target, in which case the specification has no effect and
places no additional restrictions, or it may be for the non-standard
setting (that is the opposite of the default).
In the case where the non-standard value is specified, the effect is
to renumber bits within each byte, but the ordering of bytes is not
affected. There are certain
restrictions placed on component clauses as follows:
* Components fitting within a single storage unit.
These are unrestricted, and the effect is merely to renumber bits. For
example if we are on a little-endian machine with `Low_Order_First`
being the default, then the following two declarations have exactly
the same effect:
::
type R1 is record
A : Boolean;
B : Integer range 1 .. 120;
end record;
for R1 use record
A at 0 range 0 .. 0;
B at 0 range 1 .. 7;
end record;
type R2 is record
A : Boolean;
B : Integer range 1 .. 120;
end record;
for R2'Bit_Order use High_Order_First;
for R2 use record
A at 0 range 7 .. 7;
B at 0 range 0 .. 6;
end record;
The useful application here is to write the second declaration with the
`Bit_Order` attribute definition clause, and know that it will be treated
the same, regardless of whether the target is little-endian or big-endian.
* Components occupying an integral number of bytes.
These are components that exactly fit in two or more bytes. Such component
declarations are allowed, but have no effect, since it is important to realize
that the `Bit_Order` specification does not affect the ordering of bytes.
In particular, the following attempt at getting an endian-independent integer
does not work:
::
type R2 is record
A : Integer;
end record;
for R2'Bit_Order use High_Order_First;
for R2 use record
A at 0 range 0 .. 31;
end record;
This declaration will result in a little-endian integer on a
little-endian machine, and a big-endian integer on a big-endian machine.
If byte flipping is required for interoperability between big- and
little-endian machines, this must be explicitly programmed. This capability
is not provided by `Bit_Order`.
* Components that are positioned across byte boundaries
but do not occupy an integral number of bytes. Given that bytes are not
reordered, such fields would occupy a non-contiguous sequence of bits
in memory, requiring non-trivial code to reassemble. They are for this
reason not permitted, and any component clause specifying such a layout
will be flagged as illegal by GNAT.
Since the misconception that Bit_Order automatically deals with all
endian-related incompatibilities is a common one, the specification of
a component field that is an integral number of bytes will always
generate a warning. This warning may be suppressed using `pragma Warnings (Off)`
if desired. The following section contains additional
details regarding the issue of byte ordering.
.. _Effect_of_Bit_Order_on_Byte_Ordering:
Effect of Bit_Order on Byte Ordering
====================================
.. index:: byte ordering
.. index:: ordering, of bytes
In this section we will review the effect of the `Bit_Order` attribute
definition clause on byte ordering. Briefly, it has no effect at all, but
a detailed example will be helpful. Before giving this
example, let us review the precise
definition of the effect of defining `Bit_Order`. The effect of a
non-standard bit order is described in section 15.5.3 of the Ada
Reference Manual:
"2 A bit ordering is a method of interpreting the meaning of
the storage place attributes."
To understand the precise definition of storage place attributes in
this context, we visit section 13.5.1 of the manual:
"13 A record_representation_clause (without the mod_clause)
specifies the layout. The storage place attributes (see 13.5.2)
are taken from the values of the position, first_bit, and last_bit
expressions after normalizing those values so that first_bit is
less than Storage_Unit."
The critical point here is that storage places are taken from
the values after normalization, not before. So the `Bit_Order`
interpretation applies to normalized values. The interpretation
is described in the later part of the 15.5.3 paragraph:
"2 A bit ordering is a method of interpreting the meaning of
the storage place attributes. High_Order_First (known in the
vernacular as 'big endian') means that the first bit of a
storage element (bit 0) is the most significant bit (interpreting
the sequence of bits that represent a component as an unsigned
integer value). Low_Order_First (known in the vernacular as
'little endian') means the opposite: the first bit is the
least significant."
Note that the numbering is with respect to the bits of a storage
unit. In other words, the specification affects only the numbering
of bits within a single storage unit.
We can make the effect clearer by giving an example.
Suppose that we have an external device which presents two bytes, the first
byte presented, which is the first (low addressed byte) of the two byte
record is called Master, and the second byte is called Slave.
The left most (most significant bit is called Control for each byte, and
the remaining 7 bits are called V1, V2, ... V7, where V7 is the rightmost
(least significant) bit.
On a big-endian machine, we can write the following representation clause
.. code-block:: ada
type Data is record
Master_Control : Bit;
Master_V1 : Bit;
Master_V2 : Bit;
Master_V3 : Bit;
Master_V4 : Bit;
Master_V5 : Bit;
Master_V6 : Bit;
Master_V7 : Bit;
Slave_Control : Bit;
Slave_V1 : Bit;
Slave_V2 : Bit;
Slave_V3 : Bit;
Slave_V4 : Bit;
Slave_V5 : Bit;
Slave_V6 : Bit;
Slave_V7 : Bit;
end record;
for Data use record
Master_Control at 0 range 0 .. 0;
Master_V1 at 0 range 1 .. 1;
Master_V2 at 0 range 2 .. 2;
Master_V3 at 0 range 3 .. 3;
Master_V4 at 0 range 4 .. 4;
Master_V5 at 0 range 5 .. 5;
Master_V6 at 0 range 6 .. 6;
Master_V7 at 0 range 7 .. 7;
Slave_Control at 1 range 0 .. 0;
Slave_V1 at 1 range 1 .. 1;
Slave_V2 at 1 range 2 .. 2;
Slave_V3 at 1 range 3 .. 3;
Slave_V4 at 1 range 4 .. 4;
Slave_V5 at 1 range 5 .. 5;
Slave_V6 at 1 range 6 .. 6;
Slave_V7 at 1 range 7 .. 7;
end record;
Now if we move this to a little endian machine, then the bit ordering within
the byte is backwards, so we have to rewrite the record rep clause as:
.. code-block:: ada
for Data use record
Master_Control at 0 range 7 .. 7;
Master_V1 at 0 range 6 .. 6;
Master_V2 at 0 range 5 .. 5;
Master_V3 at 0 range 4 .. 4;
Master_V4 at 0 range 3 .. 3;
Master_V5 at 0 range 2 .. 2;
Master_V6 at 0 range 1 .. 1;
Master_V7 at 0 range 0 .. 0;
Slave_Control at 1 range 7 .. 7;
Slave_V1 at 1 range 6 .. 6;
Slave_V2 at 1 range 5 .. 5;
Slave_V3 at 1 range 4 .. 4;
Slave_V4 at 1 range 3 .. 3;
Slave_V5 at 1 range 2 .. 2;
Slave_V6 at 1 range 1 .. 1;
Slave_V7 at 1 range 0 .. 0;
end record;
It is a nuisance to have to rewrite the clause, especially if
the code has to be maintained on both machines. However,
this is a case that we can handle with the
`Bit_Order` attribute if it is implemented.
Note that the implementation is not required on byte addressed
machines, but it is indeed implemented in GNAT.
This means that we can simply use the
first record clause, together with the declaration
.. code-block:: ada
for Data'Bit_Order use High_Order_First;
and the effect is what is desired, namely the layout is exactly the same,
independent of whether the code is compiled on a big-endian or little-endian
machine.
The important point to understand is that byte ordering is not affected.
A `Bit_Order` attribute definition never affects which byte a field
ends up in, only where it ends up in that byte.
To make this clear, let us rewrite the record rep clause of the previous
example as:
.. code-block:: ada
for Data'Bit_Order use High_Order_First;
for Data use record
Master_Control at 0 range 0 .. 0;
Master_V1 at 0 range 1 .. 1;
Master_V2 at 0 range 2 .. 2;
Master_V3 at 0 range 3 .. 3;
Master_V4 at 0 range 4 .. 4;
Master_V5 at 0 range 5 .. 5;
Master_V6 at 0 range 6 .. 6;
Master_V7 at 0 range 7 .. 7;
Slave_Control at 0 range 8 .. 8;
Slave_V1 at 0 range 9 .. 9;
Slave_V2 at 0 range 10 .. 10;
Slave_V3 at 0 range 11 .. 11;
Slave_V4 at 0 range 12 .. 12;
Slave_V5 at 0 range 13 .. 13;
Slave_V6 at 0 range 14 .. 14;
Slave_V7 at 0 range 15 .. 15;
end record;
This is exactly equivalent to saying (a repeat of the first example):
.. code-block:: ada
for Data'Bit_Order use High_Order_First;
for Data use record
Master_Control at 0 range 0 .. 0;
Master_V1 at 0 range 1 .. 1;
Master_V2 at 0 range 2 .. 2;
Master_V3 at 0 range 3 .. 3;
Master_V4 at 0 range 4 .. 4;
Master_V5 at 0 range 5 .. 5;
Master_V6 at 0 range 6 .. 6;
Master_V7 at 0 range 7 .. 7;
Slave_Control at 1 range 0 .. 0;
Slave_V1 at 1 range 1 .. 1;
Slave_V2 at 1 range 2 .. 2;
Slave_V3 at 1 range 3 .. 3;
Slave_V4 at 1 range 4 .. 4;
Slave_V5 at 1 range 5 .. 5;
Slave_V6 at 1 range 6 .. 6;
Slave_V7 at 1 range 7 .. 7;
end record;
Why are they equivalent? Well take a specific field, the `Slave_V2`
field. The storage place attributes are obtained by normalizing the
values given so that the `First_Bit` value is less than 8. After
normalizing the values (0,10,10) we get (1,2,2) which is exactly what
we specified in the other case.
Now one might expect that the `Bit_Order` attribute might affect
bit numbering within the entire record component (two bytes in this
case, thus affecting which byte fields end up in), but that is not
the way this feature is defined, it only affects numbering of bits,
not which byte they end up in.
Consequently it never makes sense to specify a starting bit number
greater than 7 (for a byte addressable field) if an attribute
definition for `Bit_Order` has been given, and indeed it
may be actively confusing to specify such a value, so the compiler
generates a warning for such usage.
If you do need to control byte ordering then appropriate conditional
values must be used. If in our example, the slave byte came first on
some machines we might write:
.. code-block:: ada
Master_Byte_First constant Boolean := ...;
Master_Byte : constant Natural :=
1 - Boolean'Pos (Master_Byte_First);
Slave_Byte : constant Natural :=
Boolean'Pos (Master_Byte_First);
for Data'Bit_Order use High_Order_First;
for Data use record
Master_Control at Master_Byte range 0 .. 0;
Master_V1 at Master_Byte range 1 .. 1;
Master_V2 at Master_Byte range 2 .. 2;
Master_V3 at Master_Byte range 3 .. 3;
Master_V4 at Master_Byte range 4 .. 4;
Master_V5 at Master_Byte range 5 .. 5;
Master_V6 at Master_Byte range 6 .. 6;
Master_V7 at Master_Byte range 7 .. 7;
Slave_Control at Slave_Byte range 0 .. 0;
Slave_V1 at Slave_Byte range 1 .. 1;
Slave_V2 at Slave_Byte range 2 .. 2;
Slave_V3 at Slave_Byte range 3 .. 3;
Slave_V4 at Slave_Byte range 4 .. 4;
Slave_V5 at Slave_Byte range 5 .. 5;
Slave_V6 at Slave_Byte range 6 .. 6;
Slave_V7 at Slave_Byte range 7 .. 7;
end record;
Now to switch between machines, all that is necessary is
to set the boolean constant `Master_Byte_First` in
an appropriate manner.
.. _Pragma_Pack_for_Arrays:
Pragma Pack for Arrays
======================
.. index:: Pragma Pack (for arrays)
Pragma `Pack` applied to an array has no effect unless the component type
is packable. For a component type to be packable, it must be one of the
following cases:
*
Any scalar type
*
Any type whose size is specified with a size clause
*
Any packed array type with a static size
*
Any record type padded because of its default alignment
For all these cases, if the component subtype size is in the range
1 through 63, then the effect of the pragma `Pack` is exactly as though a
component size were specified giving the component subtype size.
For example if we have:
.. code-block:: ada
type r is range 0 .. 17;
type ar is array (1 .. 8) of r;
pragma Pack (ar);
Then the component size of `ar` will be set to 5 (i.e., to `r'size`,
and the size of the array `ar` will be exactly 40 bits.
Note that in some cases this rather fierce approach to packing can produce
unexpected effects. For example, in Ada 95 and Ada 2005,
subtype `Natural` typically has a size of 31, meaning that if you
pack an array of `Natural`, you get 31-bit
close packing, which saves a few bits, but results in far less efficient
access. Since many other Ada compilers will ignore such a packing request,
GNAT will generate a warning on some uses of pragma `Pack` that it guesses
might not be what is intended. You can easily remove this warning by
using an explicit `Component_Size` setting instead, which never generates
a warning, since the intention of the programmer is clear in this case.
GNAT treats packed arrays in one of two ways. If the size of the array is
known at compile time and is less than 64 bits, then internally the array
is represented as a single modular type, of exactly the appropriate number
of bits. If the length is greater than 63 bits, or is not known at compile
time, then the packed array is represented as an array of bytes, and the
length is always a multiple of 8 bits.
Note that to represent a packed array as a modular type, the alignment must
be suitable for the modular type involved. For example, on typical machines
a 32-bit packed array will be represented by a 32-bit modular integer with
an alignment of four bytes. If you explicitly override the default alignment
with an alignment clause that is too small, the modular representation
cannot be used. For example, consider the following set of declarations:
.. code-block:: ada
type R is range 1 .. 3;
type S is array (1 .. 31) of R;
for S'Component_Size use 2;
for S'Size use 62;
for S'Alignment use 1;
If the alignment clause were not present, then a 62-bit modular
representation would be chosen (typically with an alignment of 4 or 8
bytes depending on the target). But the default alignment is overridden
with the explicit alignment clause. This means that the modular
representation cannot be used, and instead the array of bytes
representation must be used, meaning that the length must be a multiple
of 8. Thus the above set of declarations will result in a diagnostic
rejecting the size clause and noting that the minimum size allowed is 64.
.. index:: Pragma Pack (for type Natural)
.. index:: Pragma Pack warning
One special case that is worth noting occurs when the base type of the
component size is 8/16/32 and the subtype is one bit less. Notably this
occurs with subtype `Natural`. Consider:
.. code-block:: ada
type Arr is array (1 .. 32) of Natural;
pragma Pack (Arr);
In all commonly used Ada 83 compilers, this pragma Pack would be ignored,
since typically `Natural'Size` is 32 in Ada 83, and in any case most
Ada 83 compilers did not attempt 31 bit packing.
In Ada 95 and Ada 2005, `Natural'Size` is required to be 31. Furthermore,
GNAT really does pack 31-bit subtype to 31 bits. This may result in a
substantial unintended performance penalty when porting legacy Ada 83 code.
To help prevent this, GNAT generates a warning in such cases. If you really
want 31 bit packing in a case like this, you can set the component size
explicitly:
.. code-block:: ada
type Arr is array (1 .. 32) of Natural;
for Arr'Component_Size use 31;
Here 31-bit packing is achieved as required, and no warning is generated,
since in this case the programmer intention is clear.
.. _Pragma_Pack_for_Records:
Pragma Pack for Records
=======================
.. index:: Pragma Pack (for records)
Pragma `Pack` applied to a record will pack the components to reduce
wasted space from alignment gaps and by reducing the amount of space
taken by components. We distinguish between *packable* components and
*non-packable* components.
Components of the following types are considered packable:
*
Components of a primitive type are packable unless they are aliased
or of an atomic type.
*
Small packed arrays, whose size does not exceed 64 bits, and where the
size is statically known at compile time, are represented internally
as modular integers, and so they are also packable.
All packable components occupy the exact number of bits corresponding to
their `Size` value, and are packed with no padding bits, i.e., they
can start on an arbitrary bit boundary.
All other types are non-packable, they occupy an integral number of
storage units, and
are placed at a boundary corresponding to their alignment requirements.
For example, consider the record
.. code-block:: ada
type Rb1 is array (1 .. 13) of Boolean;
pragma Pack (Rb1);
type Rb2 is array (1 .. 65) of Boolean;
pragma Pack (Rb2);
type AF is new Float with Atomic;
type X2 is record
L1 : Boolean;
L2 : Duration;
L3 : AF;
L4 : Boolean;
L5 : Rb1;
L6 : Rb2;
end record;
pragma Pack (X2);
The representation for the record X2 is as follows:
.. code-block:: ada
for X2'Size use 224;
for X2 use record
L1 at 0 range 0 .. 0;
L2 at 0 range 1 .. 64;
L3 at 12 range 0 .. 31;
L4 at 16 range 0 .. 0;
L5 at 16 range 1 .. 13;
L6 at 18 range 0 .. 71;
end record;
Studying this example, we see that the packable fields `L1`
and `L2` are
of length equal to their sizes, and placed at specific bit boundaries (and
not byte boundaries) to
eliminate padding. But `L3` is of a non-packable float type (because
it is aliased), so it is on the next appropriate alignment boundary.
The next two fields are fully packable, so `L4` and `L5` are
minimally packed with no gaps. However, type `Rb2` is a packed
array that is longer than 64 bits, so it is itself non-packable. Thus
the `L6` field is aligned to the next byte boundary, and takes an
integral number of bytes, i.e., 72 bits.
.. _Record_Representation_Clauses:
Record Representation Clauses
=============================
.. index:: Record Representation Clause
Record representation clauses may be given for all record types, including
types obtained by record extension. Component clauses are allowed for any
static component. The restrictions on component clauses depend on the type
of the component.
.. index:: Component Clause
For all components of an elementary type, the only restriction on component
clauses is that the size must be at least the 'Size value of the type
(actually the Value_Size). There are no restrictions due to alignment,
and such components may freely cross storage boundaries.
Packed arrays with a size up to and including 64 bits are represented
internally using a modular type with the appropriate number of bits, and
thus the same lack of restriction applies. For example, if you declare:
.. code-block:: ada
type R is array (1 .. 49) of Boolean;
pragma Pack (R);
for R'Size use 49;
then a component clause for a component of type R may start on any
specified bit boundary, and may specify a value of 49 bits or greater.
For packed bit arrays that are longer than 64 bits, there are two
cases. If the component size is a power of 2 (1,2,4,8,16,32 bits),
including the important case of single bits or boolean values, then
there are no limitations on placement of such components, and they
may start and end at arbitrary bit boundaries.
If the component size is not a power of 2 (e.g., 3 or 5), then
an array of this type longer than 64 bits must always be placed on
on a storage unit (byte) boundary and occupy an integral number
of storage units (bytes). Any component clause that does not
meet this requirement will be rejected.
Any aliased component, or component of an aliased type, must
have its normal alignment and size. A component clause that
does not meet this requirement will be rejected.
The tag field of a tagged type always occupies an address sized field at
the start of the record. No component clause may attempt to overlay this
tag. When a tagged type appears as a component, the tag field must have
proper alignment
In the case of a record extension T1, of a type T, no component clause applied
to the type T1 can specify a storage location that would overlap the first
T'Size bytes of the record.
For all other component types, including non-bit-packed arrays,
the component can be placed at an arbitrary bit boundary,
so for example, the following is permitted:
.. code-block:: ada
type R is array (1 .. 10) of Boolean;
for R'Size use 80;
type Q is record
G, H : Boolean;
L, M : R;
end record;
for Q use record
G at 0 range 0 .. 0;
H at 0 range 1 .. 1;
L at 0 range 2 .. 81;
R at 0 range 82 .. 161;
end record;
Note: the above rules apply to recent releases of GNAT 5.
In GNAT 3, there are more severe restrictions on larger components.
For non-primitive types, including packed arrays with a size greater than
64 bits, component clauses must respect the alignment requirement of the
type, in particular, always starting on a byte boundary, and the length
must be a multiple of the storage unit.
.. _Handling_of_Records_with_Holes:
Handling of Records with Holes
==============================
.. index:: Handling of Records with Holes
As a result of alignment considerations, records may contain "holes"
or gaps
which do not correspond to the data bits of any of the components.
Record representation clauses can also result in holes in records.
GNAT does not attempt to clear these holes, so in record objects,
they should be considered to hold undefined rubbish. The generated
equality routine just tests components so does not access these
undefined bits, and assignment and copy operations may or may not
preserve the contents of these holes (for assignments, the holes
in the target will in practice contain either the bits that are
present in the holes in the source, or the bits that were present
in the target before the assignment).
If it is necessary to ensure that holes in records have all zero
bits, then record objects for which this initialization is desired
should be explicitly set to all zero values using Unchecked_Conversion
or address overlays. For example
.. code-block:: ada
type HRec is record
C : Character;
I : Integer;
end record;
On typical machines, integers need to be aligned on a four-byte
boundary, resulting in three bytes of undefined rubbish following
the 8-bit field for C. To ensure that the hole in a variable of
type HRec is set to all zero bits,
you could for example do:
.. code-block:: ada
type Base is record
Dummy1, Dummy2 : Integer := 0;
end record;
BaseVar : Base;
RealVar : Hrec;
for RealVar'Address use BaseVar'Address;
Now the 8-bytes of the value of RealVar start out containing all zero
bits. A safer approach is to just define dummy fields, avoiding the
holes, as in:
.. code-block:: ada
type HRec is record
C : Character;
Dummy1 : Short_Short_Integer := 0;
Dummy2 : Short_Short_Integer := 0;
Dummy3 : Short_Short_Integer := 0;
I : Integer;
end record;
And to make absolutely sure that the intent of this is followed, you
can use representation clauses:
.. code-block:: ada
for Hrec use record
C at 0 range 0 .. 7;
Dummy1 at 1 range 0 .. 7;
Dummy2 at 2 range 0 .. 7;
Dummy3 at 3 range 0 .. 7;
I at 4 range 0 .. 31;
end record;
for Hrec'Size use 64;
.. _Enumeration_Clauses:
Enumeration Clauses
===================
The only restriction on enumeration clauses is that the range of values
must be representable. For the signed case, if one or more of the
representation values are negative, all values must be in the range:
.. code-block:: ada
System.Min_Int .. System.Max_Int
For the unsigned case, where all values are nonnegative, the values must
be in the range:
.. code-block:: ada
0 .. System.Max_Binary_Modulus;
A *confirming* representation clause is one in which the values range
from 0 in sequence, i.e., a clause that confirms the default representation
for an enumeration type.
Such a confirming representation
is permitted by these rules, and is specially recognized by the compiler so
that no extra overhead results from the use of such a clause.
If an array has an index type which is an enumeration type to which an
enumeration clause has been applied, then the array is stored in a compact
manner. Consider the declarations:
.. code-block:: ada
type r is (A, B, C);
for r use (A => 1, B => 5, C => 10);
type t is array (r) of Character;
The array type t corresponds to a vector with exactly three elements and
has a default size equal to `3*Character'Size`. This ensures efficient
use of space, but means that accesses to elements of the array will incur
the overhead of converting representation values to the corresponding
positional values, (i.e., the value delivered by the `Pos` attribute).
.. _Address_Clauses:
Address Clauses
===============
.. index:: Address Clause
The reference manual allows a general restriction on representation clauses,
as found in RM 13.1(22):
"An implementation need not support representation
items containing nonstatic expressions, except that
an implementation should support a representation item
for a given entity if each nonstatic expression in the
representation item is a name that statically denotes
a constant declared before the entity."
In practice this is applicable only to address clauses, since this is the
only case in which a non-static expression is permitted by the syntax. As
the AARM notes in sections 13.1 (22.a-22.h):
22.a Reason: This is to avoid the following sort of thing:
22.b X : Integer := F(...);
Y : Address := G(...);
for X'Address use Y;
22.c In the above, we have to evaluate the
initialization expression for X before we
know where to put the result. This seems
like an unreasonable implementation burden.
22.d The above code should instead be written
like this:
22.e Y : constant Address := G(...);
X : Integer := F(...);
for X'Address use Y;
22.f This allows the expression 'Y' to be safely
evaluated before X is created.
22.g The constant could be a formal parameter of mode in.
22.h An implementation can support other nonstatic
expressions if it wants to. Expressions of type
Address are hardly ever static, but their value
might be known at compile time anyway in many
cases.
GNAT does indeed permit many additional cases of non-static expressions. In
particular, if the type involved is elementary there are no restrictions
(since in this case, holding a temporary copy of the initialization value,
if one is present, is inexpensive). In addition, if there is no implicit or
explicit initialization, then there are no restrictions. GNAT will reject
only the case where all three of these conditions hold:
*
The type of the item is non-elementary (e.g., a record or array).
*
There is explicit or implicit initialization required for the object.
Note that access values are always implicitly initialized.
*
The address value is non-static. Here GNAT is more permissive than the
RM, and allows the address value to be the address of a previously declared
stand-alone variable, as long as it does not itself have an address clause.
::
Anchor : Some_Initialized_Type;
Overlay : Some_Initialized_Type;
for Overlay'Address use Anchor'Address;
However, the prefix of the address clause cannot be an array component, or
a component of a discriminated record.
As noted above in section 22.h, address values are typically non-static. In
particular the To_Address function, even if applied to a literal value, is
a non-static function call. To avoid this minor annoyance, GNAT provides
the implementation defined attribute 'To_Address. The following two
expressions have identical values:
.. index:: Attribute
.. index:: To_Address
.. code-block:: ada
To_Address (16#1234_0000#)
System'To_Address (16#1234_0000#);
except that the second form is considered to be a static expression, and
thus when used as an address clause value is always permitted.
Additionally, GNAT treats as static an address clause that is an
unchecked_conversion of a static integer value. This simplifies the porting
of legacy code, and provides a portable equivalent to the GNAT attribute
`To_Address`.
Another issue with address clauses is the interaction with alignment
requirements. When an address clause is given for an object, the address
value must be consistent with the alignment of the object (which is usually
the same as the alignment of the type of the object). If an address clause
is given that specifies an inappropriately aligned address value, then the
program execution is erroneous.
Since this source of erroneous behavior can have unfortunate effects, GNAT
checks (at compile time if possible, generating a warning, or at execution
time with a run-time check) that the alignment is appropriate. If the
run-time check fails, then `Program_Error` is raised. This run-time
check is suppressed if range checks are suppressed, or if the special GNAT
check Alignment_Check is suppressed, or if
`pragma Restrictions (No_Elaboration_Code)` is in effect.
Finally, GNAT does not permit overlaying of objects of controlled types or
composite types containing a controlled component. In most cases, the compiler
can detect an attempt at such overlays and will generate a warning at compile
time and a Program_Error exception at run time.
.. index:: Export
An address clause cannot be given for an exported object. More
understandably the real restriction is that objects with an address
clause cannot be exported. This is because such variables are not
defined by the Ada program, so there is no external object to export.
.. index:: Import
It is permissible to give an address clause and a pragma Import for the
same object. In this case, the variable is not really defined by the
Ada program, so there is no external symbol to be linked. The link name
and the external name are ignored in this case. The reason that we allow this
combination is that it provides a useful idiom to avoid unwanted
initializations on objects with address clauses.
When an address clause is given for an object that has implicit or
explicit initialization, then by default initialization takes place. This
means that the effect of the object declaration is to overwrite the
memory at the specified address. This is almost always not what the
programmer wants, so GNAT will output a warning:
::
with System;
package G is
type R is record
M : Integer := 0;
end record;
Ext : R;
for Ext'Address use System'To_Address (16#1234_1234#);
|
>>> warning: implicit initialization of "Ext" may
modify overlaid storage
>>> warning: use pragma Import for "Ext" to suppress
initialization (RM B(24))
end G;
As indicated by the warning message, the solution is to use a (dummy) pragma
Import to suppress this initialization. The pragma tell the compiler that the
object is declared and initialized elsewhere. The following package compiles
without warnings (and the initialization is suppressed):
.. code-block:: ada
with System;
package G is
type R is record
M : Integer := 0;
end record;
Ext : R;
for Ext'Address use System'To_Address (16#1234_1234#);
pragma Import (Ada, Ext);
end G;
A final issue with address clauses involves their use for overlaying
variables, as in the following example:
.. index:: Overlaying of objects
.. code-block:: ada
A : Integer;
B : Integer;
for B'Address use A'Address;
or alternatively, using the form recommended by the RM:
.. code-block:: ada
A : Integer;
Addr : constant Address := A'Address;
B : Integer;
for B'Address use Addr;
In both of these cases, `A`
and `B` become aliased to one another via the
address clause. This use of address clauses to overlay
variables, achieving an effect similar to unchecked
conversion was erroneous in Ada 83, but in Ada 95 and Ada 2005
the effect is implementation defined. Furthermore, the
Ada RM specifically recommends that in a situation
like this, `B` should be subject to the following
implementation advice (RM 13.3(19)):
"19 If the Address of an object is specified, or it is imported
or exported, then the implementation should not perform
optimizations based on assumptions of no aliases."
GNAT follows this recommendation, and goes further by also applying
this recommendation to the overlaid variable (`A`
in the above example) in this case. This means that the overlay
works "as expected", in that a modification to one of the variables
will affect the value of the other.
Note that when address clause overlays are used in this way, there is an
issue of unintentional initialization, as shown by this example:
::
package Overwrite_Record is
type R is record
A : Character := 'C';
B : Character := 'A';
end record;
X : Short_Integer := 3;
Y : R;
for Y'Address use X'Address;
|
>>> warning: default initialization of "Y" may
modify "X", use pragma Import for "Y" to
suppress initialization (RM B.1(24))
end Overwrite_Record;
Here the default initialization of `Y` will clobber the value
of `X`, which justifies the warning. The warning notes that
this effect can be eliminated by adding a `pragma Import`
which suppresses the initialization:
.. code-block:: ada
package Overwrite_Record is
type R is record
A : Character := 'C';
B : Character := 'A';
end record;
X : Short_Integer := 3;
Y : R;
for Y'Address use X'Address;
pragma Import (Ada, Y);
end Overwrite_Record;
Note that the use of `pragma Initialize_Scalars` may cause variables to
be initialized when they would not otherwise have been in the absence
of the use of this pragma. This may cause an overlay to have this
unintended clobbering effect. The compiler avoids this for scalar
types, but not for composite objects (where in general the effect
of `Initialize_Scalars` is part of the initialization routine
for the composite object:
::
pragma Initialize_Scalars;
with Ada.Text_IO; use Ada.Text_IO;
procedure Overwrite_Array is
type Arr is array (1 .. 5) of Integer;
X : Arr := (others => 1);
A : Arr;
for A'Address use X'Address;
|
>>> warning: default initialization of "A" may
modify "X", use pragma Import for "A" to
suppress initialization (RM B.1(24))
begin
if X /= Arr'(others => 1) then
Put_Line ("X was clobbered");
else
Put_Line ("X was not clobbered");
end if;
end Overwrite_Array;
The above program generates the warning as shown, and at execution
time, prints `X was clobbered`. If the `pragma Import` is
added as suggested:
.. code-block:: ada
pragma Initialize_Scalars;
with Ada.Text_IO; use Ada.Text_IO;
procedure Overwrite_Array is
type Arr is array (1 .. 5) of Integer;
X : Arr := (others => 1);
A : Arr;
for A'Address use X'Address;
pragma Import (Ada, A);
begin
if X /= Arr'(others => 1) then
Put_Line ("X was clobbered");
else
Put_Line ("X was not clobbered");
end if;
end Overwrite_Array;
then the program compiles without the warning and when run will generate
the output `X was not clobbered`.
.. _Use_of_Address_Clauses_for_Memory-Mapped_I/O:
Use of Address Clauses for Memory-Mapped I/O
============================================
.. index:: Memory-mapped I/O
A common pattern is to use an address clause to map an atomic variable to
a location in memory that corresponds to a memory-mapped I/O operation or
operations, for example:
.. code-block:: ada
type Mem_Word is record
A,B,C,D : Byte;
end record;
pragma Atomic (Mem_Word);
for Mem_Word_Size use 32;
Mem : Mem_Word;
for Mem'Address use some-address;
...
Temp := Mem;
Temp.A := 32;
Mem := Temp;
For a full access (reference or modification) of the variable (Mem) in
this case, as in the above examples, GNAT guarantees that the entire atomic
word will be accessed. It is not clear whether the RM requires this. For
example in the above, can the compiler reference only the Mem.A field as
an optimization? Whatever the answer to this question is, GNAT makes the
guarantee that for such a reference, the entire word is read or written.
A problem arises with a component access such as:
.. code-block:: ada
Mem.A := 32;
Note that the component A is not declared as atomic. This means that it is
not clear what this assignment means. It could correspond to full word read
and write as given in the first example, or on architectures that supported
such an operation it might be a single byte store instruction. The RM does
not have anything to say in this situation, and GNAT does not make any
guarantee. The code generated may vary from target to target. GNAT will issue
a warning in such a case:
::
Mem.A := 32;
|
>>> warning: access to non-atomic component of atomic array,
may cause unexpected accesses to atomic object
It is best to be explicit in this situation, by either declaring the
components to be atomic if you want the byte store, or explicitly writing
the full word access sequence if that is what the hardware requires.
.. _Effect_of_Convention_on_Representation:
Effect of Convention on Representation
======================================
.. index:: Convention, effect on representation
Normally the specification of a foreign language convention for a type or
an object has no effect on the chosen representation. In particular, the
representation chosen for data in GNAT generally meets the standard system
conventions, and for example records are laid out in a manner that is
consistent with C. This means that specifying convention C (for example)
has no effect.
There are four exceptions to this general rule:
* *Convention Fortran and array subtypes*.
If pragma Convention Fortran is specified for an array subtype, then in
accordance with the implementation advice in section 3.6.2(11) of the
Ada Reference Manual, the array will be stored in a Fortran-compatible
column-major manner, instead of the normal default row-major order.
* *Convention C and enumeration types*
GNAT normally stores enumeration types in 8, 16, or 32 bits as required
to accommodate all values of the type. For example, for the enumeration
type declared by:
::
type Color is (Red, Green, Blue);
8 bits is sufficient to store all values of the type, so by default, objects
of type `Color` will be represented using 8 bits. However, normal C
convention is to use 32 bits for all enum values in C, since enum values
are essentially of type int. If pragma `Convention C` is specified for an
Ada enumeration type, then the size is modified as necessary (usually to
32 bits) to be consistent with the C convention for enum values.
Note that this treatment applies only to types. If Convention C is given for
an enumeration object, where the enumeration type is not Convention C, then
Object_Size bits are allocated. For example, for a normal enumeration type,
with less than 256 elements, only 8 bits will be allocated for the object.
Since this may be a surprise in terms of what C expects, GNAT will issue a
warning in this situation. The warning can be suppressed by giving an explicit
size clause specifying the desired size.
* *Convention C/Fortran and Boolean types*
In C, the usual convention for boolean values, that is values used for
conditions, is that zero represents false, and nonzero values represent
true. In Ada, the normal convention is that two specific values, typically
0/1, are used to represent false/true respectively.
Fortran has a similar convention for `LOGICAL` values (any nonzero
value represents true).
To accommodate the Fortran and C conventions, if a pragma Convention specifies
C or Fortran convention for a derived Boolean, as in the following example:
::
type C_Switch is new Boolean;
pragma Convention (C, C_Switch);
then the GNAT generated code will treat any nonzero value as true. For truth
values generated by GNAT, the conventional value 1 will be used for True, but
when one of these values is read, any nonzero value is treated as True.
.. _Conventions_and_Anonymous_Access_Types:
Conventions and Anonymous Access Types
======================================
.. index:: Anonymous access types
.. index:: Convention for anonymous access types
The RM is not entirely clear on convention handling in a number of cases,
and in particular, it is not clear on the convention to be given to
anonymous access types in general, and in particular what is to be
done for the case of anonymous access-to-subprogram.
In GNAT, we decide that if an explicit Convention is applied
to an object or component, and its type is such an anonymous type,
then the convention will apply to this anonymous type as well. This
seems to make sense since it is anomolous in any case to have a
different convention for an object and its type, and there is clearly
no way to explicitly specify a convention for an anonymous type, since
it doesn't have a name to specify!
Furthermore, we decide that if a convention is applied to a record type,
then this convention is inherited by any of its components that are of an
anonymous access type which do not have an explicitly specified convention.
The following program shows these conventions in action:
::
package ConvComp is
type Foo is range 1 .. 10;
type T1 is record
A : access function (X : Foo) return Integer;
B : Integer;
end record;
pragma Convention (C, T1);
type T2 is record
A : access function (X : Foo) return Integer;
pragma Convention (C, A);
B : Integer;
end record;
pragma Convention (COBOL, T2);
type T3 is record
A : access function (X : Foo) return Integer;
pragma Convention (COBOL, A);
B : Integer;
end record;
pragma Convention (C, T3);
type T4 is record
A : access function (X : Foo) return Integer;
B : Integer;
end record;
pragma Convention (COBOL, T4);
function F (X : Foo) return Integer;
pragma Convention (C, F);
function F (X : Foo) return Integer is (13);
TV1 : T1 := (F'Access, 12); -- OK
TV2 : T2 := (F'Access, 13); -- OK
TV3 : T3 := (F'Access, 13); -- ERROR
|
>>> subprogram "F" has wrong convention
>>> does not match access to subprogram declared at line 17
38. TV4 : T4 := (F'Access, 13); -- ERROR
|
>>> subprogram "F" has wrong convention
>>> does not match access to subprogram declared at line 24
39. end ConvComp;
.. _Determining_the_Representations_chosen_by_GNAT:
Determining the Representations chosen by GNAT
==============================================
.. index:: Representation, determination of
.. index:: -gnatR (gcc)
Although the descriptions in this section are intended to be complete, it is
often easier to simply experiment to see what GNAT accepts and what the
effect is on the layout of types and objects.
As required by the Ada RM, if a representation clause is not accepted, then
it must be rejected as illegal by the compiler. However, when a
representation clause or pragma is accepted, there can still be questions
of what the compiler actually does. For example, if a partial record
representation clause specifies the location of some components and not
others, then where are the non-specified components placed? Or if pragma
`Pack` is used on a record, then exactly where are the resulting
fields placed? The section on pragma `Pack` in this chapter can be
used to answer the second question, but it is often easier to just see
what the compiler does.
For this purpose, GNAT provides the option *-gnatR*. If you compile
with this option, then the compiler will output information on the actual
representations chosen, in a format similar to source representation
clauses. For example, if we compile the package:
.. code-block:: ada
package q is
type r (x : boolean) is tagged record
case x is
when True => S : String (1 .. 100);
when False => null;
end case;
end record;
type r2 is new r (false) with record
y2 : integer;
end record;
for r2 use record
y2 at 16 range 0 .. 31;
end record;
type x is record
y : character;
end record;
type x1 is array (1 .. 10) of x;
for x1'component_size use 11;
type ia is access integer;
type Rb1 is array (1 .. 13) of Boolean;
pragma Pack (rb1);
type Rb2 is array (1 .. 65) of Boolean;
pragma Pack (rb2);
type x2 is record
l1 : Boolean;
l2 : Duration;
l3 : Float;
l4 : Boolean;
l5 : Rb1;
l6 : Rb2;
end record;
pragma Pack (x2);
end q;
using the switch *-gnatR* we obtain the following output:
.. code-block:: ada
Representation information for unit q
-------------------------------------
for r'Size use ??;
for r'Alignment use 4;
for r use record
x at 4 range 0 .. 7;
_tag at 0 range 0 .. 31;
s at 5 range 0 .. 799;
end record;
for r2'Size use 160;
for r2'Alignment use 4;
for r2 use record
x at 4 range 0 .. 7;
_tag at 0 range 0 .. 31;
_parent at 0 range 0 .. 63;
y2 at 16 range 0 .. 31;
end record;
for x'Size use 8;
for x'Alignment use 1;
for x use record
y at 0 range 0 .. 7;
end record;
for x1'Size use 112;
for x1'Alignment use 1;
for x1'Component_Size use 11;
for rb1'Size use 13;
for rb1'Alignment use 2;
for rb1'Component_Size use 1;
for rb2'Size use 72;
for rb2'Alignment use 1;
for rb2'Component_Size use 1;
for x2'Size use 224;
for x2'Alignment use 4;
for x2 use record
l1 at 0 range 0 .. 0;
l2 at 0 range 1 .. 64;
l3 at 12 range 0 .. 31;
l4 at 16 range 0 .. 0;
l5 at 16 range 1 .. 13;
l6 at 18 range 0 .. 71;
end record;
The Size values are actually the Object_Size, i.e., the default size that
will be allocated for objects of the type.
The ``??`` size for type r indicates that we have a variant record, and the
actual size of objects will depend on the discriminant value.
The Alignment values show the actual alignment chosen by the compiler
for each record or array type.
The record representation clause for type r shows where all fields
are placed, including the compiler generated tag field (whose location
cannot be controlled by the programmer).
The record representation clause for the type extension r2 shows all the
fields present, including the parent field, which is a copy of the fields
of the parent type of r2, i.e., r1.
The component size and size clauses for types rb1 and rb2 show
the exact effect of pragma `Pack` on these arrays, and the record
representation clause for type x2 shows how pragma `Pack` affects
this record type.
In some cases, it may be useful to cut and paste the representation clauses
generated by the compiler into the original source to fix and guarantee
the actual representation to be used.
.. _Specialized_Needs_Annexes:
*************************
Specialized Needs Annexes
*************************
Ada 95, Ada 2005, and Ada 2012 define a number of Specialized Needs Annexes, which are not
required in all implementations. However, as described in this chapter,
GNAT implements all of these annexes:
*Systems Programming (Annex C)*
The Systems Programming Annex is fully implemented.
*Real-Time Systems (Annex D)*
The Real-Time Systems Annex is fully implemented.
*Distributed Systems (Annex E)*
Stub generation is fully implemented in the GNAT compiler. In addition,
a complete compatible PCS is available as part of the GLADE system,
a separate product. When the two
products are used in conjunction, this annex is fully implemented.
*Information Systems (Annex F)*
The Information Systems annex is fully implemented.
*Numerics (Annex G)*
The Numerics Annex is fully implemented.
*Safety and Security / High-Integrity Systems (Annex H)*
The Safety and Security Annex (termed the High-Integrity Systems Annex
in Ada 2005) is fully implemented.
.. _Standard_and_Implementation_Defined_Restrictions:
************************************************
Standard and Implementation Defined Restrictions
************************************************
All Ada Reference Manual-defined Restriction identifiers are implemented:
* language-defined restrictions (see 13.12.1)
* tasking restrictions (see D.7)
* high integrity restrictions (see H.4)
GNAT implements additional restriction identifiers. All restrictions, whether
language defined or GNAT-specific, are listed in the following.
.. _Partition-Wide_Restrictions:
Partition-Wide Restrictions
===========================
There are two separate lists of restriction identifiers. The first
set requires consistency throughout a partition (in other words, if the
restriction identifier is used for any compilation unit in the partition,
then all compilation units in the partition must obey the restriction).
Immediate_Reclamation
---------------------
.. index:: Immediate_Reclamation
[RM H.4] This restriction ensures that, except for storage occupied by
objects created by allocators and not deallocated via unchecked
deallocation, any storage reserved at run time for an object is
immediately reclaimed when the object no longer exists.
Max_Asynchronous_Select_Nesting
-------------------------------
.. index:: Max_Asynchronous_Select_Nesting
[RM D.7] Specifies the maximum dynamic nesting level of asynchronous
selects. Violations of this restriction with a value of zero are
detected at compile time. Violations of this restriction with values
other than zero cause Storage_Error to be raised.
Max_Entry_Queue_Length
----------------------
.. index:: Max_Entry_Queue_Length
[RM D.7] This restriction is a declaration that any protected entry compiled in
the scope of the restriction has at most the specified number of
tasks waiting on the entry at any one time, and so no queue is required.
Note that this restriction is checked at run time. Violation of this
restriction results in the raising of Program_Error exception at the point of
the call.
.. index:: Max_Entry_Queue_Depth
The restriction `Max_Entry_Queue_Depth` is recognized as a
synonym for `Max_Entry_Queue_Length`. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
Max_Protected_Entries
---------------------
.. index:: Max_Protected_Entries
[RM D.7] Specifies the maximum number of entries per protected type. The
bounds of every entry family of a protected unit shall be static, or shall be
defined by a discriminant of a subtype whose corresponding bound is static.
Max_Select_Alternatives
-----------------------
.. index:: Max_Select_Alternatives
[RM D.7] Specifies the maximum number of alternatives in a selective accept.
Max_Storage_At_Blocking
-----------------------
.. index:: Max_Storage_At_Blocking
[RM D.7] Specifies the maximum portion (in storage elements) of a task's
Storage_Size that can be retained by a blocked task. A violation of this
restriction causes Storage_Error to be raised.
Max_Task_Entries
----------------
.. index:: Max_Task_Entries
[RM D.7] Specifies the maximum number of entries
per task. The bounds of every entry family
of a task unit shall be static, or shall be
defined by a discriminant of a subtype whose
corresponding bound is static.
Max_Tasks
---------
.. index:: Max_Tasks
[RM D.7] Specifies the maximum number of task that may be created, not
counting the creation of the environment task. Violations of this
restriction with a value of zero are detected at compile
time. Violations of this restriction with values other than zero cause
Storage_Error to be raised.
No_Abort_Statements
-------------------
.. index:: No_Abort_Statements
[RM D.7] There are no abort_statements, and there are
no calls to Task_Identification.Abort_Task.
No_Access_Parameter_Allocators
------------------------------
.. index:: No_Access_Parameter_Allocators
[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator as the actual parameter to an access
parameter.
No_Access_Subprograms
---------------------
.. index:: No_Access_Subprograms
[RM H.4] This restriction ensures at compile time that there are no
declarations of access-to-subprogram types.
No_Allocators
-------------
.. index:: No_Allocators
[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator.
No_Anonymous_Allocators
-----------------------
.. index:: No_Anonymous_Allocators
[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator of anonymous access type.
No_Calendar
-----------
.. index:: No_Calendar
[GNAT] This restriction ensures at compile time that there is no implicit or
explicit dependence on the package `Ada.Calendar`.
No_Coextensions
---------------
.. index:: No_Coextensions
[RM H.4] This restriction ensures at compile time that there are no
coextensions. See 3.10.2.
No_Default_Initialization
-------------------------
.. index:: No_Default_Initialization
[GNAT] This restriction prohibits any instance of default initialization
of variables. The binder implements a consistency rule which prevents
any unit compiled without the restriction from with'ing a unit with the
restriction (this allows the generation of initialization procedures to
be skipped, since you can be sure that no call is ever generated to an
initialization procedure in a unit with the restriction active). If used
in conjunction with Initialize_Scalars or Normalize_Scalars, the effect
is to prohibit all cases of variables declared without a specific
initializer (including the case of OUT scalar parameters).
No_Delay
--------
.. index:: No_Delay
[RM H.4] This restriction ensures at compile time that there are no
delay statements and no dependences on package Calendar.
No_Dependence
-------------
.. index:: No_Dependence
[RM 13.12.1] This restriction checks at compile time that there are no
dependence on a library unit.
No_Direct_Boolean_Operators
---------------------------
.. index:: No_Direct_Boolean_Operators
[GNAT] This restriction ensures that no logical operators (and/or/xor)
are used on operands of type Boolean (or any type derived from Boolean).
This is intended for use in safety critical programs where the certification
protocol requires the use of short-circuit (and then, or else) forms for all
composite boolean operations.
No_Dispatch
-----------
.. index:: No_Dispatch
[RM H.4] This restriction ensures at compile time that there are no
occurrences of `T'Class`, for any (tagged) subtype `T`.
No_Dispatching_Calls
--------------------
.. index:: No_Dispatching_Calls
[GNAT] This restriction ensures at compile time that the code generated by the
compiler involves no dispatching calls. The use of this restriction allows the
safe use of record extensions, classwide membership tests and other classwide
features not involving implicit dispatching. This restriction ensures that
the code contains no indirect calls through a dispatching mechanism. Note that
this includes internally-generated calls created by the compiler, for example
in the implementation of class-wide objects assignments. The
membership test is allowed in the presence of this restriction, because its
implementation requires no dispatching.
This restriction is comparable to the official Ada restriction
`No_Dispatch` except that it is a bit less restrictive in that it allows
all classwide constructs that do not imply dispatching.
The following example indicates constructs that violate this restriction.
.. code-block:: ada
package Pkg is
type T is tagged record
Data : Natural;
end record;
procedure P (X : T);
type DT is new T with record
More_Data : Natural;
end record;
procedure Q (X : DT);
end Pkg;
with Pkg; use Pkg;
procedure Example is
procedure Test (O : T'Class) is
N : Natural := O'Size;-- Error: Dispatching call
C : T'Class := O; -- Error: implicit Dispatching Call
begin
if O in DT'Class then -- OK : Membership test
Q (DT (O)); -- OK : Type conversion plus direct call
else
P (O); -- Error: Dispatching call
end if;
end Test;
Obj : DT;
begin
P (Obj); -- OK : Direct call
P (T (Obj)); -- OK : Type conversion plus direct call
P (T'Class (Obj)); -- Error: Dispatching call
Test (Obj); -- OK : Type conversion
if Obj in T'Class then -- OK : Membership test
null;
end if;
end Example;
No_Dynamic_Attachment
---------------------
.. index:: No_Dynamic_Attachment
[RM D.7] This restriction ensures that there is no call to any of the
operations defined in package Ada.Interrupts
(Is_Reserved, Is_Attached, Current_Handler, Attach_Handler, Exchange_Handler,
Detach_Handler, and Reference).
.. index:: No_Dynamic_Interrupts
The restriction `No_Dynamic_Interrupts` is recognized as a
synonym for `No_Dynamic_Attachment`. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
No_Dynamic_Priorities
---------------------
.. index:: No_Dynamic_Priorities
[RM D.7] There are no semantic dependencies on the package Dynamic_Priorities.
No_Entry_Calls_In_Elaboration_Code
----------------------------------
.. index:: No_Entry_Calls_In_Elaboration_Code
[GNAT] This restriction ensures at compile time that no task or protected entry
calls are made during elaboration code. As a result of the use of this
restriction, the compiler can assume that no code past an accept statement
in a task can be executed at elaboration time.
No_Enumeration_Maps
-------------------
.. index:: No_Enumeration_Maps
[GNAT] This restriction ensures at compile time that no operations requiring
enumeration maps are used (that is Image and Value attributes applied
to enumeration types).
No_Exception_Handlers
---------------------
.. index:: No_Exception_Handlers
[GNAT] This restriction ensures at compile time that there are no explicit
exception handlers. It also indicates that no exception propagation will
be provided. In this mode, exceptions may be raised but will result in
an immediate call to the last chance handler, a routine that the user
must define with the following profile:
.. code-block:: ada
procedure Last_Chance_Handler
(Source_Location : System.Address; Line : Integer);
pragma Export (C, Last_Chance_Handler,
"__gnat_last_chance_handler");
The parameter is a C null-terminated string representing a message to be
associated with the exception (typically the source location of the raise
statement generated by the compiler). The Line parameter when nonzero
represents the line number in the source program where the raise occurs.
No_Exception_Propagation
------------------------
.. index:: No_Exception_Propagation
[GNAT] This restriction guarantees that exceptions are never propagated
to an outer subprogram scope. The only case in which an exception may
be raised is when the handler is statically in the same subprogram, so
that the effect of a raise is essentially like a goto statement. Any
other raise statement (implicit or explicit) will be considered
unhandled. Exception handlers are allowed, but may not contain an
exception occurrence identifier (exception choice). In addition, use of
the package GNAT.Current_Exception is not permitted, and reraise
statements (raise with no operand) are not permitted.
No_Exception_Registration
-------------------------
.. index:: No_Exception_Registration
[GNAT] This restriction ensures at compile time that no stream operations for
types Exception_Id or Exception_Occurrence are used. This also makes it
impossible to pass exceptions to or from a partition with this restriction
in a distributed environment. If this restriction is active, the generated
code is simplified by omitting the otherwise-required global registration
of exceptions when they are declared.
No_Exceptions
-------------
.. index:: No_Exceptions
[RM H.4] This restriction ensures at compile time that there are no
raise statements and no exception handlers.
No_Finalization
---------------
.. index:: No_Finalization
[GNAT] This restriction disables the language features described in
chapter 7.6 of the Ada 2005 RM as well as all form of code generation
performed by the compiler to support these features. The following types
are no longer considered controlled when this restriction is in effect:
*
`Ada.Finalization.Controlled`
*
`Ada.Finalization.Limited_Controlled`
*
Derivations from `Controlled` or `Limited_Controlled`
*
Class-wide types
*
Protected types
*
Task types
*
Array and record types with controlled components
The compiler no longer generates code to initialize, finalize or adjust an
object or a nested component, either declared on the stack or on the heap. The
deallocation of a controlled object no longer finalizes its contents.
No_Fixed_Point
--------------
.. index:: No_Fixed_Point
[RM H.4] This restriction ensures at compile time that there are no
occurrences of fixed point types and operations.
No_Floating_Point
-----------------
.. index:: No_Floating_Point
[RM H.4] This restriction ensures at compile time that there are no
occurrences of floating point types and operations.
No_Implicit_Conditionals
------------------------
.. index:: No_Implicit_Conditionals
[GNAT] This restriction ensures that the generated code does not contain any
implicit conditionals, either by modifying the generated code where possible,
or by rejecting any construct that would otherwise generate an implicit
conditional. Note that this check does not include run time constraint
checks, which on some targets may generate implicit conditionals as
well. To control the latter, constraint checks can be suppressed in the
normal manner. Constructs generating implicit conditionals include comparisons
of composite objects and the Max/Min attributes.
No_Implicit_Dynamic_Code
------------------------
.. index:: No_Implicit_Dynamic_Code
.. index:: trampoline
[GNAT] This restriction prevents the compiler from building 'trampolines'.
This is a structure that is built on the stack and contains dynamic
code to be executed at run time. On some targets, a trampoline is
built for the following features: `Access`,
`Unrestricted_Access`, or `Address` of a nested subprogram;
nested task bodies; primitive operations of nested tagged types.
Trampolines do not work on machines that prevent execution of stack
data. For example, on windows systems, enabling DEP (data execution
protection) will cause trampolines to raise an exception.
Trampolines are also quite slow at run time.
On many targets, trampolines have been largely eliminated. Look at the
version of system.ads for your target --- if it has
Always_Compatible_Rep equal to False, then trampolines are largely
eliminated. In particular, a trampoline is built for the following
features: `Address` of a nested subprogram;
`Access` or `Unrestricted_Access` of a nested subprogram,
but only if pragma Favor_Top_Level applies, or the access type has a
foreign-language convention; primitive operations of nested tagged
types.
No_Implicit_Heap_Allocations
----------------------------
.. index:: No_Implicit_Heap_Allocations
[RM D.7] No constructs are allowed to cause implicit heap allocation.
No_Implicit_Loops
-----------------
.. index:: No_Implicit_Loops
[GNAT] This restriction ensures that the generated code does not contain any
implicit `for` loops, either by modifying
the generated code where possible,
or by rejecting any construct that would otherwise generate an implicit
`for` loop. If this restriction is active, it is possible to build
large array aggregates with all static components without generating an
intermediate temporary, and without generating a loop to initialize individual
components. Otherwise, a loop is created for arrays larger than about 5000
scalar components.
No_Initialize_Scalars
---------------------
.. index:: No_Initialize_Scalars
[GNAT] This restriction ensures that no unit in the partition is compiled with
pragma Initialize_Scalars. This allows the generation of more efficient
code, and in particular eliminates dummy null initialization routines that
are otherwise generated for some record and array types.
No_IO
-----
.. index:: No_IO
[RM H.4] This restriction ensures at compile time that there are no
dependences on any of the library units Sequential_IO, Direct_IO,
Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, or Stream_IO.
No_Local_Allocators
-------------------
.. index:: No_Local_Allocators
[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator in subprograms, generic subprograms, tasks,
and entry bodies.
No_Local_Protected_Objects
--------------------------
.. index:: No_Local_Protected_Objects
[RM D.7] This restriction ensures at compile time that protected objects are
only declared at the library level.
No_Local_Timing_Events
----------------------
.. index:: No_Local_Timing_Events
[RM D.7] All objects of type Ada.Timing_Events.Timing_Event are
declared at the library level.
No_Long_Long_Integers
---------------------
.. index:: No_Long_Long_Integers
[GNAT] This partition-wide restriction forbids any explicit reference to
type Standard.Long_Long_Integer, and also forbids declaring range types whose
implicit base type is Long_Long_Integer, and modular types whose size exceeds
Long_Integer'Size.
No_Multiple_Elaboration
-----------------------
.. index:: No_Multiple_Elaboration
[GNAT] Normally each package contains a 16-bit counter used to check for access
before elaboration, and to control multiple elaboration attempts.
This counter is eliminated for units compiled with the static model
of elaboration if restriction `No_Elaboration_Code`
is active but because of
the need to check for multiple elaboration in the general case, these
counters cannot be eliminated if elaboration code may be present. The
restriction `No_Multiple_Elaboration`
allows suppression of these counters
in static elaboration units even if they do have elaboration code. If this
restriction is used, then the situations in which multiple elaboration is
possible, including non-Ada main programs, and Stand Alone libraries, are not
permitted, and will be diagnosed by the binder.
No_Nested_Finalization
----------------------
.. index:: No_Nested_Finalization
[RM D.7] All objects requiring finalization are declared at the library level.
No_Protected_Type_Allocators
----------------------------
.. index:: No_Protected_Type_Allocators
[RM D.7] This restriction ensures at compile time that there are no allocator
expressions that attempt to allocate protected objects.
No_Protected_Types
------------------
.. index:: No_Protected_Types
[RM H.4] This restriction ensures at compile time that there are no
declarations of protected types or protected objects.
No_Recursion
------------
.. index:: No_Recursion
[RM H.4] A program execution is erroneous if a subprogram is invoked as
part of its execution.
No_Reentrancy
-------------
.. index:: No_Reentrancy
[RM H.4] A program execution is erroneous if a subprogram is executed by
two tasks at the same time.
No_Relative_Delay
-----------------
.. index:: No_Relative_Delay
[RM D.7] This restriction ensures at compile time that there are no delay
relative statements and prevents expressions such as `delay 1.23;` from
appearing in source code.
No_Requeue_Statements
---------------------
.. index:: No_Requeue_Statements
[RM D.7] This restriction ensures at compile time that no requeue statements
are permitted and prevents keyword `requeue` from being used in source
code.
.. index:: No_Requeue
The restriction `No_Requeue` is recognized as a
synonym for `No_Requeue_Statements`. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on oNobsolescent features are activated).
No_Secondary_Stack
------------------
.. index:: No_Secondary_Stack
[GNAT] This restriction ensures at compile time that the generated code
does not contain any reference to the secondary stack. The secondary
stack is used to implement functions returning unconstrained objects
(arrays or records) on some targets.
No_Select_Statements
--------------------
.. index:: No_Select_Statements
[RM D.7] This restriction ensures at compile time no select statements of any
kind are permitted, that is the keyword `select` may not appear.
No_Specific_Termination_Handlers
--------------------------------
.. index:: No_Specific_Termination_Handlers
[RM D.7] There are no calls to Ada.Task_Termination.Set_Specific_Handler
or to Ada.Task_Termination.Specific_Handler.
No_Specification_of_Aspect
--------------------------
.. index:: No_Specification_of_Aspect
[RM 13.12.1] This restriction checks at compile time that no aspect
specification, attribute definition clause, or pragma is given for a
given aspect.
No_Standard_Allocators_After_Elaboration
----------------------------------------
.. index:: No_Standard_Allocators_After_Elaboration
[RM D.7] Specifies that an allocator using a standard storage pool
should never be evaluated at run time after the elaboration of the
library items of the partition has completed. Otherwise, Storage_Error
is raised.
No_Standard_Storage_Pools
-------------------------
.. index:: No_Standard_Storage_Pools
[GNAT] This restriction ensures at compile time that no access types
use the standard default storage pool. Any access type declared must
have an explicit Storage_Pool attribute defined specifying a
user-defined storage pool.
No_Stream_Optimizations
-----------------------
.. index:: No_Stream_Optimizations
[GNAT] This restriction affects the performance of stream operations on types
`String`, `Wide_String` and `Wide_Wide_String`. By default, the
compiler uses block reads and writes when manipulating `String` objects
due to their supperior performance. When this restriction is in effect, the
compiler performs all IO operations on a per-character basis.
No_Streams
----------
.. index:: No_Streams
[GNAT] This restriction ensures at compile/bind time that there are no
stream objects created and no use of stream attributes.
This restriction does not forbid dependences on the package
`Ada.Streams`. So it is permissible to with
`Ada.Streams` (or another package that does so itself)
as long as no actual stream objects are created and no
stream attributes are used.
Note that the use of restriction allows optimization of tagged types,
since they do not need to worry about dispatching stream operations.
To take maximum advantage of this space-saving optimization, any
unit declaring a tagged type should be compiled with the restriction,
though this is not required.
No_Task_Allocators
------------------
.. index:: No_Task_Allocators
[RM D.7] There are no allocators for task types
or types containing task subcomponents.
No_Task_Attributes_Package
--------------------------
.. index:: No_Task_Attributes_Package
[GNAT] This restriction ensures at compile time that there are no implicit or
explicit dependencies on the package `Ada.Task_Attributes`.
.. index:: No_Task_Attributes
The restriction `No_Task_Attributes` is recognized as a synonym
for `No_Task_Attributes_Package`. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
No_Task_Hierarchy
-----------------
.. index:: No_Task_Hierarchy
[RM D.7] All (non-environment) tasks depend
directly on the environment task of the partition.
No_Task_Termination
-------------------
.. index:: No_Task_Termination
[RM D.7] Tasks that terminate are erroneous.
No_Tasking
----------
.. index:: No_Tasking
[GNAT] This restriction prevents the declaration of tasks or task types
throughout the partition. It is similar in effect to the use of
`Max_Tasks => 0` except that violations are caught at compile time
and cause an error message to be output either by the compiler or
binder.
No_Terminate_Alternatives
-------------------------
.. index:: No_Terminate_Alternatives
[RM D.7] There are no selective accepts with terminate alternatives.
No_Unchecked_Access
-------------------
.. index:: No_Unchecked_Access
[RM H.4] This restriction ensures at compile time that there are no
occurrences of the Unchecked_Access attribute.
No_Use_Of_Entity
----------------
.. index:: No_Use_Of_Entity
[GNAT] This restriction ensures at compile time that there are no references
to the entity given in the form ::
No_Use_Of_Entity => Name
where ``Name`` is the fully qualified entity, for example ::
No_Use_Of_Entity => Ada.Text_IO.Put_Line
Simple_Barriers
---------------
.. index:: Simple_Barriers
[RM D.7] This restriction ensures at compile time that barriers in entry
declarations for protected types are restricted to either static boolean
expressions or references to simple boolean variables defined in the private
part of the protected type. No other form of entry barriers is permitted.
.. index:: Boolean_Entry_Barriers
The restriction `Boolean_Entry_Barriers` is recognized as a
synonym for `Simple_Barriers`. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
Static_Priorities
-----------------
.. index:: Static_Priorities
[GNAT] This restriction ensures at compile time that all priority expressions
are static, and that there are no dependences on the package
`Ada.Dynamic_Priorities`.
Static_Storage_Size
-------------------
.. index:: Static_Storage_Size
[GNAT] This restriction ensures at compile time that any expression appearing
in a Storage_Size pragma or attribute definition clause is static.
.. _Program_Unit_Level_Restrictions:
Program Unit Level Restrictions
===============================
The second set of restriction identifiers
does not require partition-wide consistency.
The restriction may be enforced for a single
compilation unit without any effect on any of the
other compilation units in the partition.
No_Elaboration_Code
-------------------
.. index:: No_Elaboration_Code
[GNAT] This restriction ensures at compile time that no elaboration code is
generated. Note that this is not the same condition as is enforced
by pragma `Preelaborate`. There are cases in which pragma
`Preelaborate` still permits code to be generated (e.g., code
to initialize a large array to all zeroes), and there are cases of units
which do not meet the requirements for pragma `Preelaborate`,
but for which no elaboration code is generated. Generally, it is
the case that preelaborable units will meet the restrictions, with
the exception of large aggregates initialized with an others_clause,
and exception declarations (which generate calls to a run-time
registry procedure). This restriction is enforced on
a unit by unit basis, it need not be obeyed consistently
throughout a partition.
In the case of aggregates with others, if the aggregate has a dynamic
size, there is no way to eliminate the elaboration code (such dynamic
bounds would be incompatible with `Preelaborate` in any case). If
the bounds are static, then use of this restriction actually modifies
the code choice of the compiler to avoid generating a loop, and instead
generate the aggregate statically if possible, no matter how many times
the data for the others clause must be repeatedly generated.
It is not possible to precisely document
the constructs which are compatible with this restriction, since,
unlike most other restrictions, this is not a restriction on the
source code, but a restriction on the generated object code. For
example, if the source contains a declaration:
.. code-block:: ada
Val : constant Integer := X;
where X is not a static constant, it may be possible, depending
on complex optimization circuitry, for the compiler to figure
out the value of X at compile time, in which case this initialization
can be done by the loader, and requires no initialization code. It
is not possible to document the precise conditions under which the
optimizer can figure this out.
Note that this the implementation of this restriction requires full
code generation. If it is used in conjunction with "semantics only"
checking, then some cases of violations may be missed.
No_Entry_Queue
--------------
.. index:: No_Entry_Queue
[GNAT] This restriction is a declaration that any protected entry compiled in
the scope of the restriction has at most one task waiting on the entry
at any one time, and so no queue is required. This restriction is not
checked at compile time. A program execution is erroneous if an attempt
is made to queue a second task on such an entry.
No_Implementation_Aspect_Specifications
---------------------------------------
.. index:: No_Implementation_Aspect_Specifications
[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined aspects are present. With this restriction, the only
aspects that can be used are those defined in the Ada Reference Manual.
No_Implementation_Attributes
----------------------------
.. index:: No_Implementation_Attributes
[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined attributes are present. With this restriction, the only
attributes that can be used are those defined in the Ada Reference
Manual.
No_Implementation_Identifiers
-----------------------------
.. index:: No_Implementation_Identifiers
[RM 13.12.1] This restriction checks at compile time that no
implementation-defined identifiers (marked with pragma Implementation_Defined)
occur within language-defined packages.
No_Implementation_Pragmas
-------------------------
.. index:: No_Implementation_Pragmas
[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined pragmas are present. With this restriction, the only
pragmas that can be used are those defined in the Ada Reference Manual.
No_Implementation_Restrictions
------------------------------
.. index:: No_Implementation_Restrictions
[GNAT] This restriction checks at compile time that no GNAT-defined restriction
identifiers (other than `No_Implementation_Restrictions` itself)
are present. With this restriction, the only other restriction identifiers
that can be used are those defined in the Ada Reference Manual.
No_Implementation_Units
-----------------------
.. index:: No_Implementation_Units
[RM 13.12.1] This restriction checks at compile time that there is no
mention in the context clause of any implementation-defined descendants
of packages Ada, Interfaces, or System.
No_Implicit_Aliasing
--------------------
.. index:: No_Implicit_Aliasing
[GNAT] This restriction, which is not required to be partition-wide consistent,
requires an explicit aliased keyword for an object to which 'Access,
'Unchecked_Access, or 'Address is applied, and forbids entirely the use of
the 'Unrestricted_Access attribute for objects. Note: the reason that
Unrestricted_Access is forbidden is that it would require the prefix
to be aliased, and in such cases, it can always be replaced by
the standard attribute Unchecked_Access which is preferable.
No_Obsolescent_Features
-----------------------
.. index:: No_Obsolescent_Features
[RM 13.12.1] This restriction checks at compile time that no obsolescent
features are used, as defined in Annex J of the Ada Reference Manual.
No_Wide_Characters
------------------
.. index:: No_Wide_Characters
[GNAT] This restriction ensures at compile time that no uses of the types
`Wide_Character` or `Wide_String` or corresponding wide
wide types
appear, and that no wide or wide wide string or character literals
appear in the program (that is literals representing characters not in
type `Character`).
SPARK_05
--------
.. index:: SPARK_05
[GNAT] This restriction checks at compile time that some constructs
forbidden in SPARK 2005 are not present. Error messages related to
SPARK restriction have the form:
::
violation of restriction "SPARK_05" at <source-location>
<error message>
.. index:: SPARK
The restriction `SPARK` is recognized as a
synonym for `SPARK_05`. This is retained for historical
compatibility purposes (and an unconditional warning will be generated
for its use, advising replacement by `SPARK`).
This is not a replacement for the semantic checks performed by the
SPARK Examiner tool, as the compiler currently only deals with code,
not SPARK 2005 annotations, and does not guarantee catching all
cases of constructs forbidden by SPARK 2005.
Thus it may well be the case that code which passes the compiler with
the SPARK restriction is rejected by the SPARK Examiner, e.g. due to
the different visibility rules of the Examiner based on SPARK 2005
`inherit` annotations.
This restriction can be useful in providing an initial filter for code
developed using SPARK 2005, or in examining legacy code to see how far
it is from meeting SPARK restrictions.
The list below summarizes the checks that are performed when this
restriction is in force:
* No block statements
* No case statements with only an others clause
* Exit statements in loops must respect the SPARK 2005 language restrictions
* No goto statements
* Return can only appear as last statement in function
* Function must have return statement
* Loop parameter specification must include subtype mark
* Prefix of expanded name cannot be a loop statement
* Abstract subprogram not allowed
* User-defined operators not allowed
* Access type parameters not allowed
* Default expressions for parameters not allowed
* Default expressions for record fields not allowed
* No tasking constructs allowed
* Label needed at end of subprograms and packages
* No mixing of positional and named parameter association
* No access types as result type
* No unconstrained arrays as result types
* No null procedures
* Initial and later declarations must be in correct order (declaration can't come after body)
* No attributes on private types if full declaration not visible
* No package declaration within package specification
* No controlled types
* No discriminant types
* No overloading
* Selector name cannot be operator symbol (i.e. operator symbol cannot be prefixed)
* Access attribute not allowed
* Allocator not allowed
* Result of catenation must be String
* Operands of catenation must be string literal, static char or another catenation
* No conditional expressions
* No explicit dereference
* Quantified expression not allowed
* Slicing not allowed
* No exception renaming
* No generic renaming
* No object renaming
* No use clause
* Aggregates must be qualified
* Non-static choice in array aggregates not allowed
* The only view conversions which are allowed as in-out parameters are conversions of a tagged type to an ancestor type
* No mixing of positional and named association in aggregate, no multi choice
* AND, OR and XOR for arrays only allowed when operands have same static bounds
* Fixed point operands to * or / must be qualified or converted
* Comparison operators not allowed for Booleans or arrays (except strings)
* Equality not allowed for arrays with non-matching static bounds (except strings)
* Conversion / qualification not allowed for arrays with non-matching static bounds
* Subprogram declaration only allowed in package spec (unless followed by import)
* Access types not allowed
* Incomplete type declaration not allowed
* Object and subtype declarations must respect SPARK restrictions
* Digits or delta constraint not allowed
* Decimal fixed point type not allowed
* Aliasing of objects not allowed
* Modular type modulus must be power of 2
* Base not allowed on subtype mark
* Unary operators not allowed on modular types (except not)
* Untagged record cannot be null
* No class-wide operations
* Initialization expressions must respect SPARK restrictions
* Non-static ranges not allowed except in iteration schemes
* String subtypes must have lower bound of 1
* Subtype of Boolean cannot have constraint
* At most one tagged type or extension per package
* Interface is not allowed
* Character literal cannot be prefixed (selector name cannot be character literal)
* Record aggregate cannot contain 'others'
* Component association in record aggregate must contain a single choice
* Ancestor part cannot be a type mark
* Attributes 'Image, 'Width and 'Value not allowed
* Functions may not update globals
* Subprograms may not contain direct calls to themselves (prevents recursion within unit)
* Call to subprogram not allowed in same unit before body has been seen (prevents recursion within unit)
The following restrictions are enforced, but note that they are actually more
strict that the latest SPARK 2005 language definition:
* No derived types other than tagged type extensions
* Subtype of unconstrained array must have constraint
This list summarises the main SPARK 2005 language rules that are not
currently checked by the SPARK_05 restriction:
* SPARK annotations are treated as comments so are not checked at all
* Based real literals not allowed
* Objects cannot be initialized at declaration by calls to user-defined functions
* Objects cannot be initialized at declaration by assignments from variables
* Objects cannot be initialized at declaration by assignments from indexed/selected components
* Ranges shall not be null
* A fixed point delta expression must be a simple expression
* Restrictions on where renaming declarations may be placed
* Externals of mode 'out' cannot be referenced
* Externals of mode 'in' cannot be updated
* Loop with no iteration scheme or exits only allowed as last statement in main program or task
* Subprogram cannot have parent unit name
* SPARK 2005 inherited subprogram must be prefixed with overriding
* External variables (or functions that reference them) may not be passed as actual parameters
* Globals must be explicitly mentioned in contract
* Deferred constants cannot be completed by pragma Import
* Package initialization cannot read/write variables from other packages
* Prefix not allowed for entities that are directly visible
* Identifier declaration can't override inherited package name
* Cannot use Standard or other predefined packages as identifiers
* After renaming, cannot use the original name
* Subprograms can only be renamed to remove package prefix
* Pragma import must be immediately after entity it names
* No mutual recursion between multiple units (this can be checked with gnatcheck)
Note that if a unit is compiled in Ada 95 mode with the SPARK restriction,
violations will be reported for constructs forbidden in SPARK 95,
instead of SPARK 2005.
.. _Standard_Library_Routines:
*************************
Standard Library Routines
*************************
The Ada Reference Manual contains in Annex A a full description of an
extensive set of standard library routines that can be used in any Ada
program, and which must be provided by all Ada compilers. They are
analogous to the standard C library used by C programs.
GNAT implements all of the facilities described in annex A, and for most
purposes the description in the Ada Reference Manual, or appropriate Ada
text book, will be sufficient for making use of these facilities.
In the case of the input-output facilities,
:ref:`The_Implementation_of_Standard_I/O`,
gives details on exactly how GNAT interfaces to the
file system. For the remaining packages, the Ada Reference Manual
should be sufficient. The following is a list of the packages included,
together with a brief description of the functionality that is provided.
For completeness, references are included to other predefined library
routines defined in other sections of the Ada Reference Manual (these are
cross-indexed from Annex A). For further details see the relevant
package declarations in the run-time library. In particular, a few units
are not implemented, as marked by the presence of pragma Unimplemented_Unit,
and in this case the package declaration contains comments explaining why
the unit is not implemented.
``Ada`` *(A.2)*
This is a parent package for all the standard library packages. It is
usually included implicitly in your program, and itself contains no
useful data or routines.
``Ada.Assertions`` *(11.4.2)*
`Assertions` provides the `Assert` subprograms, and also
the declaration of the `Assertion_Error` exception.
``Ada.Asynchronous_Task_Control`` *(D.11)*
`Asynchronous_Task_Control` provides low level facilities for task
synchronization. It is typically not implemented. See package spec for details.
``Ada.Calendar`` *(9.6)*
`Calendar` provides time of day access, and routines for
manipulating times and durations.
``Ada.Calendar.Arithmetic`` *(9.6.1)*
This package provides additional arithmetic
operations for `Calendar`.
``Ada.Calendar.Formatting`` *(9.6.1)*
This package provides formatting operations for `Calendar`.
``Ada.Calendar.Time_Zones`` *(9.6.1)*
This package provides additional `Calendar` facilities
for handling time zones.
``Ada.Characters`` *(A.3.1)*
This is a dummy parent package that contains no useful entities
``Ada.Characters.Conversions`` *(A.3.2)*
This package provides character conversion functions.
``Ada.Characters.Handling`` *(A.3.2)*
This package provides some basic character handling capabilities,
including classification functions for classes of characters (e.g., test
for letters, or digits).
``Ada.Characters.Latin_1`` *(A.3.3)*
This package includes a complete set of definitions of the characters
that appear in type CHARACTER. It is useful for writing programs that
will run in international environments. For example, if you want an
upper case E with an acute accent in a string, it is often better to use
the definition of `UC_E_Acute` in this package. Then your program
will print in an understandable manner even if your environment does not
support these extended characters.
``Ada.Command_Line`` *(A.15)*
This package provides access to the command line parameters and the name
of the current program (analogous to the use of `argc` and `argv`
in C), and also allows the exit status for the program to be set in a
system-independent manner.
``Ada.Complex_Text_IO`` *(G.1.3)*
This package provides text input and output of complex numbers.
``Ada.Containers`` *(A.18.1)*
A top level package providing a few basic definitions used by all the
following specific child packages that provide specific kinds of
containers.
``Ada.Containers.Bounded_Priority_Queues`` *(A.18.31)*
``Ada.Containers.Bounded_Synchronized_Queues`` *(A.18.29)*
``Ada.Containers.Doubly_Linked_Lists`` *(A.18.3)*
``Ada.Containers.Generic_Array_Sort`` *(A.18.26)*
``Ada.Containers.Generic_Constrained_Array_Sort`` *(A.18.26)*
``Ada.Containers.Generic_Sort`` *(A.18.26)*
``Ada.Containers.Hashed_Maps`` *(A.18.5)*
``Ada.Containers.Hashed_Sets`` *(A.18.8)*
``Ada.Containers.Indefinite_Doubly_Linked_Lists`` *(A.18.12)*
``Ada.Containers.Indefinite_Hashed_Maps`` *(A.18.13)*
``Ada.Containers.Indefinite_Hashed_Sets`` *(A.18.15)*
``Ada.Containers.Indefinite_Holders`` *(A.18.18)*
``Ada.Containers.Indefinite_Multiway_Trees`` *(A.18.17)*
``Ada.Containers.Indefinite_Ordered_Maps`` *(A.18.14)*
``Ada.Containers.Indefinite_Ordered_Sets`` *(A.18.16)*
``Ada.Containers.Indefinite_Vectors`` *(A.18.11)*
``Ada.Containers.Multiway_Trees`` *(A.18.10)*
``Ada.Containers.Ordered_Maps`` *(A.18.6)*
``Ada.Containers.Ordered_Sets`` *(A.18.9)*
``Ada.Containers.Synchronized_Queue_Interfaces`` *(A.18.27)*
``Ada.Containers.Unbounded_Priority_Queues`` *(A.18.30)*
``Ada.Containers.Unbounded_Synchronized_Queues`` *(A.18.28)*
``Ada.Containers.Vectors`` *(A.18.2)*
``Ada.Directories`` *(A.16)*
This package provides operations on directories.
``Ada.Directories.Hierarchical_File_Names`` *(A.16.1)*
This package provides additional directory operations handling
hiearchical file names.
``Ada.Directories.Information`` *(A.16)*
This is an implementation defined package for additional directory
operations, which is not implemented in GNAT.
``Ada.Decimal`` *(F.2)*
This package provides constants describing the range of decimal numbers
implemented, and also a decimal divide routine (analogous to the COBOL
verb DIVIDE ... GIVING ... REMAINDER ...)
``Ada.Direct_IO`` *(A.8.4)*
This package provides input-output using a model of a set of records of
fixed-length, containing an arbitrary definite Ada type, indexed by an
integer record number.
``Ada.Dispatching`` *(D.2.1)*
A parent package containing definitions for task dispatching operations.
``Ada.Dispatching.EDF`` *(D.2.6)*
Not implemented in GNAT.
``Ada.Dispatching.Non_Preemptive`` *(D.2.4)*
Not implemented in GNAT.
``Ada.Dispatching.Round_Robin`` *(D.2.5)*
Not implemented in GNAT.
``Ada.Dynamic_Priorities`` *(D.5)*
This package allows the priorities of a task to be adjusted dynamically
as the task is running.
``Ada.Environment_Variables`` *(A.17)*
This package provides facilities for accessing environment variables.
``Ada.Exceptions`` *(11.4.1)*
This package provides additional information on exceptions, and also
contains facilities for treating exceptions as data objects, and raising
exceptions with associated messages.
``Ada.Execution_Time`` *(D.14)*
Not implemented in GNAT.
``Ada.Execution_Time.Group_Budgets`` *(D.14.2)*
Not implemented in GNAT.
``Ada.Execution_Time.Timers`` *(D.14.1)'*
Not implemented in GNAT.
``Ada.Finalization`` *(7.6)*
This package contains the declarations and subprograms to support the
use of controlled types, providing for automatic initialization and
finalization (analogous to the constructors and destructors of C++).
``Ada.Float_Text_IO`` *(A.10.9)*
A library level instantiation of Text_IO.Float_IO for type Float.
``Ada.Float_Wide_Text_IO`` *(A.10.9)*
A library level instantiation of Wide_Text_IO.Float_IO for type Float.
``Ada.Float_Wide_Wide_Text_IO`` *(A.10.9)*
A library level instantiation of Wide_Wide_Text_IO.Float_IO for type Float.
``Ada.Integer_Text_IO`` *(A.10.9)*
A library level instantiation of Text_IO.Integer_IO for type Integer.
``Ada.Integer_Wide_Text_IO`` *(A.10.9)*
A library level instantiation of Wide_Text_IO.Integer_IO for type Integer.
``Ada.Integer_Wide_Wide_Text_IO`` *(A.10.9)*
A library level instantiation of Wide_Wide_Text_IO.Integer_IO for type Integer.
``Ada.Interrupts`` *(C.3.2)*
This package provides facilities for interfacing to interrupts, which
includes the set of signals or conditions that can be raised and
recognized as interrupts.
``Ada.Interrupts.Names`` *(C.3.2)*
This package provides the set of interrupt names (actually signal
or condition names) that can be handled by GNAT.
``Ada.IO_Exceptions`` *(A.13)*
This package defines the set of exceptions that can be raised by use of
the standard IO packages.
``Ada.Iterator_Interfaces`` *(5.5.1)*
This package provides a generic interface to generalized iterators.
``Ada.Locales`` *(A.19)*
This package provides declarations providing information (Language
and Country) about the current locale.
``Ada.Numerics``
This package contains some standard constants and exceptions used
throughout the numerics packages. Note that the constants pi and e are
defined here, and it is better to use these definitions than rolling
your own.
``Ada.Numerics.Complex_Arrays`` *(G.3.2)*
Provides operations on arrays of complex numbers.
``Ada.Numerics.Complex_Elementary_Functions``
Provides the implementation of standard elementary functions (such as
log and trigonometric functions) operating on complex numbers using the
standard `Float` and the `Complex` and `Imaginary` types
created by the package `Numerics.Complex_Types`.
``Ada.Numerics.Complex_Types``
This is a predefined instantiation of
`Numerics.Generic_Complex_Types` using `Standard.Float` to
build the type `Complex` and `Imaginary`.
``Ada.Numerics.Discrete_Random``
This generic package provides a random number generator suitable for generating
uniformly distributed values of a specified discrete subtype.
``Ada.Numerics.Float_Random``
This package provides a random number generator suitable for generating
uniformly distributed floating point values in the unit interval.
``Ada.Numerics.Generic_Complex_Elementary_Functions``
This is a generic version of the package that provides the
implementation of standard elementary functions (such as log and
trigonometric functions) for an arbitrary complex type.
The following predefined instantiations of this package are provided:
* ``Short_Float``
`Ada.Numerics.Short_Complex_Elementary_Functions`
* ``Float``
`Ada.Numerics.Complex_Elementary_Functions`
* ``Long_Float``
`Ada.Numerics.Long_Complex_Elementary_Functions`
``Ada.Numerics.Generic_Complex_Types``
This is a generic package that allows the creation of complex types,
with associated complex arithmetic operations.
The following predefined instantiations of this package exist
* ``Short_Float``
`Ada.Numerics.Short_Complex_Complex_Types`
* ``Float``
`Ada.Numerics.Complex_Complex_Types`
* ``Long_Float``
`Ada.Numerics.Long_Complex_Complex_Types`
``Ada.Numerics.Generic_Elementary_Functions``
This is a generic package that provides the implementation of standard
elementary functions (such as log an trigonometric functions) for an
arbitrary float type.
The following predefined instantiations of this package exist
* ``Short_Float``
`Ada.Numerics.Short_Elementary_Functions`
* ``Float``
`Ada.Numerics.Elementary_Functions`
* ``Long_Float``
`Ada.Numerics.Long_Elementary_Functions`
``Ada.Numerics.Generic_Real_Arrays`` *(G.3.1)*
Generic operations on arrays of reals
``Ada.Numerics.Real_Arrays`` *(G.3.1)*
Preinstantiation of Ada.Numerics.Generic_Real_Arrays (Float).
``Ada.Real_Time`` *(D.8)*
This package provides facilities similar to those of `Calendar`, but
operating with a finer clock suitable for real time control. Note that
annex D requires that there be no backward clock jumps, and GNAT generally
guarantees this behavior, but of course if the external clock on which
the GNAT runtime depends is deliberately reset by some external event,
then such a backward jump may occur.
``Ada.Real_Time.Timing_Events`` *(D.15)*
Not implemented in GNAT.
``Ada.Sequential_IO`` *(A.8.1)*
This package provides input-output facilities for sequential files,
which can contain a sequence of values of a single type, which can be
any Ada type, including indefinite (unconstrained) types.
``Ada.Storage_IO`` *(A.9)*
This package provides a facility for mapping arbitrary Ada types to and
from a storage buffer. It is primarily intended for the creation of new
IO packages.
``Ada.Streams`` *(13.13.1)*
This is a generic package that provides the basic support for the
concept of streams as used by the stream attributes (`Input`,
`Output`, `Read` and `Write`).
``Ada.Streams.Stream_IO`` *(A.12.1)*
This package is a specialization of the type `Streams` defined in
package `Streams` together with a set of operations providing
Stream_IO capability. The Stream_IO model permits both random and
sequential access to a file which can contain an arbitrary set of values
of one or more Ada types.
``Ada.Strings`` *(A.4.1)*
This package provides some basic constants used by the string handling
packages.
``Ada.Strings.Bounded`` *(A.4.4)*
This package provides facilities for handling variable length
strings. The bounded model requires a maximum length. It is thus
somewhat more limited than the unbounded model, but avoids the use of
dynamic allocation or finalization.
``Ada.Strings.Bounded.Equal_Case_Insensitive`` *(A.4.10)*
Provides case-insensitive comparisons of bounded strings
``Ada.Strings.Bounded.Hash`` *(A.4.9)*
This package provides a generic hash function for bounded strings
``Ada.Strings.Bounded.Hash_Case_Insensitive`` *(A.4.9)*
This package provides a generic hash function for bounded strings that
converts the string to be hashed to lower case.
``Ada.Strings.Bounded.Less_Case_Insensitive`` *(A.4.10)*
This package provides a comparison function for bounded strings that works
in a case insensitive manner by converting to lower case before the comparison.
``Ada.Strings.Fixed`` *(A.4.3)*
This package provides facilities for handling fixed length strings.
``Ada.Strings.Fixed.Equal_Case_Insensitive`` *(A.4.10)*
This package provides an equality function for fixed strings that compares
the strings after converting both to lower case.
``Ada.Strings.Fixed.Hash_Case_Insensitive`` *(A.4.9)*
This package provides a case insensitive hash function for fixed strings that
converts the string to lower case before computing the hash.
``Ada.Strings.Fixed.Less_Case_Insensitive`` *(A.4.10)*
This package provides a comparison function for fixed strings that works
in a case insensitive manner by converting to lower case before the comparison.
``Ada.Strings.Hash`` *(A.4.9)*
This package provides a hash function for strings.
``Ada.Strings.Hash_Case_Insensitive`` *(A.4.9)*
This package provides a hash function for strings that is case insensitive.
The string is converted to lower case before computing the hash.
``Ada.Strings.Less_Case_Insensitive`` *(A.4.10)*
This package provides a comparison function for\\strings that works
in a case insensitive manner by converting to lower case before the comparison.
``Ada.Strings.Maps`` *(A.4.2)*
This package provides facilities for handling character mappings and
arbitrarily defined subsets of characters. For instance it is useful in
defining specialized translation tables.
``Ada.Strings.Maps.Constants`` *(A.4.6)*
This package provides a standard set of predefined mappings and
predefined character sets. For example, the standard upper to lower case
conversion table is found in this package. Note that upper to lower case
conversion is non-trivial if you want to take the entire set of
characters, including extended characters like E with an acute accent,
into account. You should use the mappings in this package (rather than
adding 32 yourself) to do case mappings.
``Ada.Strings.Unbounded`` *(A.4.5)*
This package provides facilities for handling variable length
strings. The unbounded model allows arbitrary length strings, but
requires the use of dynamic allocation and finalization.
``Ada.Strings.Unbounded.Equal_Case_Insensitive`` *(A.4.10)*
Provides case-insensitive comparisons of unbounded strings
``Ada.Strings.Unbounded.Hash`` *(A.4.9)*
This package provides a generic hash function for unbounded strings
``Ada.Strings.Unbounded.Hash_Case_Insensitive`` *(A.4.9)*
This package provides a generic hash function for unbounded strings that
converts the string to be hashed to lower case.
``Ada.Strings.Unbounded.Less_Case_Insensitive`` *(A.4.10)*
This package provides a comparison function for unbounded strings that works
in a case insensitive manner by converting to lower case before the comparison.
``Ada.Strings.UTF_Encoding`` *(A.4.11)*
This package provides basic definitions for dealing with UTF-encoded strings.
``Ada.Strings.UTF_Encoding.Conversions`` *(A.4.11)*
This package provides conversion functions for UTF-encoded strings.
``Ada.Strings.UTF_Encoding.Strings`` *(A.4.11)*
``Ada.Strings.UTF_Encoding.Wide_Strings`` *(A.4.11)*
``Ada.Strings.UTF_Encoding.Wide_Wide_Strings`` *(A.4.11)*
These packages provide facilities for handling UTF encodings for
Strings, Wide_Strings and Wide_Wide_Strings.
``Ada.Strings.Wide_Bounded`` *(A.4.7)*
``Ada.Strings.Wide_Fixed`` *(A.4.7)*
``Ada.Strings.Wide_Maps`` *(A.4.7)*
``Ada.Strings.Wide_Unbounded`` *(A.4.7)*
These packages provide analogous capabilities to the corresponding
packages without ``Wide_`` in the name, but operate with the types
`Wide_String` and `Wide_Character` instead of `String`
and `Character`. Versions of all the child packages are available.
``Ada.Strings.Wide_Wide_Bounded`` *(A.4.7)*
``Ada.Strings.Wide_Wide_Fixed`` *(A.4.7)*
``Ada.Strings.Wide_Wide_Maps`` *(A.4.7)*
``Ada.Strings.Wide_Wide_Unbounded`` *(A.4.7)*
These packages provide analogous capabilities to the corresponding
packages without ``Wide_`` in the name, but operate with the types
`Wide_Wide_String` and `Wide_Wide_Character` instead
of `String` and `Character`.
``Ada.Synchronous_Barriers`` *(D.10.1)*
This package provides facilities for synchronizing tasks at a low level
with barriers.
``Ada.Synchronous_Task_Control`` *(D.10)*
This package provides some standard facilities for controlling task
communication in a synchronous manner.
``Ada.Synchronous_Task_Control.EDF`` *(D.10)*
Not implemented in GNAT.
``Ada.Tags``
This package contains definitions for manipulation of the tags of tagged
values.
``Ada.Tags.Generic_Dispatching_Constructor`` *(3.9)*
This package provides a way of constructing tagged class-wide values given
only the tag value.
``Ada.Task_Attributes`` *(C.7.2)*
This package provides the capability of associating arbitrary
task-specific data with separate tasks.
``Ada.Task_Identifification`` *(C.7.1)*
This package provides capabilities for task identification.
``Ada.Task_Termination`` *(C.7.3)*
This package provides control over task termination.
``Ada.Text_IO``
This package provides basic text input-output capabilities for
character, string and numeric data. The subpackages of this
package are listed next. Note that although these are defined
as subpackages in the RM, they are actually transparently
implemented as child packages in GNAT, meaning that they
are only loaded if needed.
``Ada.Text_IO.Decimal_IO``
Provides input-output facilities for decimal fixed-point types
``Ada.Text_IO.Enumeration_IO``
Provides input-output facilities for enumeration types.
``Ada.Text_IO.Fixed_IO``
Provides input-output facilities for ordinary fixed-point types.
``Ada.Text_IO.Float_IO``
Provides input-output facilities for float types. The following
predefined instantiations of this generic package are available:
* ``Short_Float``
`Short_Float_Text_IO`
* ``Float``
`Float_Text_IO`
* ``Long_Float``
`Long_Float_Text_IO`
``Ada.Text_IO.Integer_IO``
Provides input-output facilities for integer types. The following
predefined instantiations of this generic package are available:
* ``Short_Short_Integer``
`Ada.Short_Short_Integer_Text_IO`
* ``Short_Integer``
`Ada.Short_Integer_Text_IO`
* ``Integer``
`Ada.Integer_Text_IO`
* ``Long_Integer``
`Ada.Long_Integer_Text_IO`
* ``Long_Long_Integer``
`Ada.Long_Long_Integer_Text_IO`
``Ada.Text_IO.Modular_IO``
Provides input-output facilities for modular (unsigned) types.
``Ada.Text_IO.Bounded_IO (A.10.11)``
Provides input-output facilities for bounded strings.
``Ada.Text_IO.Complex_IO (G.1.3)``
This package provides basic text input-output capabilities for complex
data.
``Ada.Text_IO.Editing (F.3.3)``
This package contains routines for edited output, analogous to the use
of pictures in COBOL. The picture formats used by this package are a
close copy of the facility in COBOL.
``Ada.Text_IO.Text_Streams (A.12.2)``
This package provides a facility that allows Text_IO files to be treated
as streams, so that the stream attributes can be used for writing
arbitrary data, including binary data, to Text_IO files.
``Ada.Text_IO.Unbounded_IO (A.10.12)``
This package provides input-output facilities for unbounded strings.
``Ada.Unchecked_Conversion (13.9)``
This generic package allows arbitrary conversion from one type to
another of the same size, providing for breaking the type safety in
special circumstances.
If the types have the same Size (more accurately the same Value_Size),
then the effect is simply to transfer the bits from the source to the
target type without any modification. This usage is well defined, and
for simple types whose representation is typically the same across
all implementations, gives a portable method of performing such
conversions.
If the types do not have the same size, then the result is implementation
defined, and thus may be non-portable. The following describes how GNAT
handles such unchecked conversion cases.
If the types are of different sizes, and are both discrete types, then
the effect is of a normal type conversion without any constraint checking.
In particular if the result type has a larger size, the result will be
zero or sign extended. If the result type has a smaller size, the result
will be truncated by ignoring high order bits.
If the types are of different sizes, and are not both discrete types,
then the conversion works as though pointers were created to the source
and target, and the pointer value is converted. The effect is that bits
are copied from successive low order storage units and bits of the source
up to the length of the target type.
A warning is issued if the lengths differ, since the effect in this
case is implementation dependent, and the above behavior may not match
that of some other compiler.
A pointer to one type may be converted to a pointer to another type using
unchecked conversion. The only case in which the effect is undefined is
when one or both pointers are pointers to unconstrained array types. In
this case, the bounds information may get incorrectly transferred, and in
particular, GNAT uses double size pointers for such types, and it is
meaningless to convert between such pointer types. GNAT will issue a
warning if the alignment of the target designated type is more strict
than the alignment of the source designated type (since the result may
be unaligned in this case).
A pointer other than a pointer to an unconstrained array type may be
converted to and from System.Address. Such usage is common in Ada 83
programs, but note that Ada.Address_To_Access_Conversions is the
preferred method of performing such conversions in Ada 95 and Ada 2005.
Neither
unchecked conversion nor Ada.Address_To_Access_Conversions should be
used in conjunction with pointers to unconstrained objects, since
the bounds information cannot be handled correctly in this case.
``Ada.Unchecked_Deallocation`` *(13.11.2)*
This generic package allows explicit freeing of storage previously
allocated by use of an allocator.
``Ada.Wide_Text_IO`` *(A.11)*
This package is similar to `Ada.Text_IO`, except that the external
file supports wide character representations, and the internal types are
`Wide_Character` and `Wide_String` instead of `Character`
and `String`. The corresponding set of nested packages and child
packages are defined.
``Ada.Wide_Wide_Text_IO`` *(A.11)*
This package is similar to `Ada.Text_IO`, except that the external
file supports wide character representations, and the internal types are
`Wide_Character` and `Wide_String` instead of `Character`
and `String`. The corresponding set of nested packages and child
packages are defined.
For packages in Interfaces and System, all the RM defined packages are
available in GNAT, see the Ada 2012 RM for full details.
.. _The_GNAT_Library:
****************
The GNAT Library
****************
The GNAT library contains a number of general and special purpose packages.
It represents functionality that the GNAT developers have found useful, and
which is made available to GNAT users. The packages described here are fully
supported, and upwards compatibility will be maintained in future releases,
so you can use these facilities with the confidence that the same functionality
will be available in future releases.
The chapter here simply gives a brief summary of the facilities available.
The full documentation is found in the spec file for the package. The full
sources of these library packages, including both spec and body, are provided
with all GNAT releases. For example, to find out the full specifications of
the SPITBOL pattern matching capability, including a full tutorial and
extensive examples, look in the :file:`g-spipat.ads` file in the library.
For each entry here, the package name (as it would appear in a `with`
clause) is given, followed by the name of the corresponding spec file in
parentheses. The packages are children in four hierarchies, `Ada`,
`Interfaces`, `System`, and `GNAT`, the latter being a
GNAT-specific hierarchy.
Note that an application program should only use packages in one of these
four hierarchies if the package is defined in the Ada Reference Manual,
or is listed in this section of the GNAT Programmers Reference Manual.
All other units should be considered internal implementation units and
should not be directly `with`'ed by application code. The use of
a `with` statement that references one of these internal implementation
units makes an application potentially dependent on changes in versions
of GNAT, and will generate a warning message.
.. _`Ada.Characters.Latin_9_(a-chlat9.ads)`:
`Ada.Characters.Latin_9` (:file:`a-chlat9.ads`)
===============================================
.. index:: Ada.Characters.Latin_9 (a-chlat9.ads)
.. index:: Latin_9 constants for Character
This child of `Ada.Characters`
provides a set of definitions corresponding to those in the
RM-defined package `Ada.Characters.Latin_1` but with the
few modifications required for `Latin-9`
The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
.. _`Ada.Characters.Wide_Latin_1_(a-cwila1.ads)`:
`Ada.Characters.Wide_Latin_1` (:file:`a-cwila1.ads`)
====================================================
.. index:: Ada.Characters.Wide_Latin_1 (a-cwila1.ads)
.. index:: Latin_1 constants for Wide_Character
This child of `Ada.Characters`
provides a set of definitions corresponding to those in the
RM-defined package `Ada.Characters.Latin_1` but with the
types of the constants being `Wide_Character`
instead of `Character`. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
.. _`Ada.Characters.Wide_Latin_9_(a-cwila1.ads)`:
`Ada.Characters.Wide_Latin_9` (:file:`a-cwila1.ads`)
====================================================
.. index:: Ada.Characters.Wide_Latin_9 (a-cwila1.ads)
.. index:: Latin_9 constants for Wide_Character
This child of `Ada.Characters`
provides a set of definitions corresponding to those in the
GNAT defined package `Ada.Characters.Latin_9` but with the
types of the constants being `Wide_Character`
instead of `Character`. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
.. _`Ada.Characters.Wide_Wide_Latin_1_(a-chzla1.ads)`:
`Ada.Characters.Wide_Wide_Latin_1` (:file:`a-chzla1.ads`)
=========================================================
.. index:: Ada.Characters.Wide_Wide_Latin_1 (a-chzla1.ads)
.. index:: Latin_1 constants for Wide_Wide_Character
This child of `Ada.Characters`
provides a set of definitions corresponding to those in the
RM-defined package `Ada.Characters.Latin_1` but with the
types of the constants being `Wide_Wide_Character`
instead of `Character`. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
.. _`Ada.Characters.Wide_Wide_Latin_9_(a-chzla9.ads)`:
`Ada.Characters.Wide_Wide_Latin_9` (:file:`a-chzla9.ads`)
=========================================================
.. index:: Ada.Characters.Wide_Wide_Latin_9 (a-chzla9.ads)
.. index:: Latin_9 constants for Wide_Wide_Character
This child of `Ada.Characters`
provides a set of definitions corresponding to those in the
GNAT defined package `Ada.Characters.Latin_9` but with the
types of the constants being `Wide_Wide_Character`
instead of `Character`. The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
.. _`Ada.Containers.Formal_Doubly_Linked_Lists_(a-cfdlli.ads)`:
`Ada.Containers.Formal_Doubly_Linked_Lists` (:file:`a-cfdlli.ads`)
==================================================================
.. index:: Ada.Containers.Formal_Doubly_Linked_Lists (a-cfdlli.ads)
.. index:: Formal container for doubly linked lists
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for doubly linked lists, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Hashed_Maps_(a-cfhama.ads)`:
`Ada.Containers.Formal_Hashed_Maps` (:file:`a-cfhama.ads`)
==========================================================
.. index:: Ada.Containers.Formal_Hashed_Maps (a-cfhama.ads)
.. index:: Formal container for hashed maps
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for hashed maps, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Hashed_Sets_(a-cfhase.ads)`:
`Ada.Containers.Formal_Hashed_Sets` (:file:`a-cfhase.ads`)
==========================================================
.. index:: Ada.Containers.Formal_Hashed_Sets (a-cfhase.ads)
.. index:: Formal container for hashed sets
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for hashed sets, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Ordered_Maps_(a-cforma.ads)`:
`Ada.Containers.Formal_Ordered_Maps` (:file:`a-cforma.ads`)
===========================================================
.. index:: Ada.Containers.Formal_Ordered_Maps (a-cforma.ads)
.. index:: Formal container for ordered maps
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for ordered maps, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Ordered_Sets_(a-cforse.ads)`:
`Ada.Containers.Formal_Ordered_Sets` (:file:`a-cforse.ads`)
===========================================================
.. index:: Ada.Containers.Formal_Ordered_Sets (a-cforse.ads)
.. index:: Formal container for ordered sets
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for ordered sets, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Vectors_(a-cofove.ads)`:
`Ada.Containers.Formal_Vectors` (:file:`a-cofove.ads`)
======================================================
.. index:: Ada.Containers.Formal_Vectors (a-cofove.ads)
.. index:: Formal container for vectors
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for vectors, meant to facilitate formal
verification of code using such containers. The specification of this
unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Formal_Indefinite_Vectors_(a-cfinve.ads)`:
`Ada.Containers.Formal_Indefinite_Vectors` (:file:`a-cfinve.ads`)
=================================================================
.. index:: Ada.Containers.Formal_Indefinite_Vectors (a-cfinve.ads)
.. index:: Formal container for vectors
This child of `Ada.Containers` defines a modified version of the
Ada 2005 container for vectors of indefinite elements, meant to
facilitate formal verification of code using such containers. The
specification of this unit is compatible with SPARK 2014.
Note that although this container was designed with formal verification
in mind, it may well be generally useful in that it is a simplified more
efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
.. _`Ada.Containers.Bounded_Holders_(a-coboho.ads)`:
`Ada.Containers.Bounded_Holders` (:file:`a-coboho.ads`)
=======================================================
.. index:: Ada.Containers.Bounded_Holders (a-coboho.ads)
.. index:: Formal container for vectors
This child of `Ada.Containers` defines a modified version of
Indefinite_Holders that avoids heap allocation.
.. _`Ada.Command_Line.Environment_(a-colien.ads)`:
`Ada.Command_Line.Environment` (:file:`a-colien.ads`)
=====================================================
.. index:: Ada.Command_Line.Environment (a-colien.ads)
.. index:: Environment entries
This child of `Ada.Command_Line`
provides a mechanism for obtaining environment values on systems
where this concept makes sense.
.. _`Ada.Command_Line.Remove_(a-colire.ads)`:
`Ada.Command_Line.Remove` (:file:`a-colire.ads`)
================================================
.. index:: Ada.Command_Line.Remove (a-colire.ads)
.. index:: Removing command line arguments
.. index:: Command line, argument removal
This child of `Ada.Command_Line`
provides a mechanism for logically removing
arguments from the argument list. Once removed, an argument is not visible
to further calls on the subprograms in `Ada.Command_Line` will not
see the removed argument.
.. _`Ada.Command_Line.Response_File_(a-clrefi.ads)`:
`Ada.Command_Line.Response_File` (:file:`a-clrefi.ads`)
=======================================================
.. index:: Ada.Command_Line.Response_File (a-clrefi.ads)
.. index:: Response file for command line
.. index:: Command line, response file
.. index:: Command line, handling long command lines
This child of `Ada.Command_Line` provides a mechanism facilities for
getting command line arguments from a text file, called a "response file".
Using a response file allow passing a set of arguments to an executable longer
than the maximum allowed by the system on the command line.
.. _`Ada.Direct_IO.C_Streams_(a-diocst.ads)`:
`Ada.Direct_IO.C_Streams` (:file:`a-diocst.ads`)
================================================
.. index:: Ada.Direct_IO.C_Streams (a-diocst.ads)
.. index:: C Streams, Interfacing with Direct_IO
This package provides subprograms that allow interfacing between
C streams and `Direct_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Exceptions.Is_Null_Occurrence_(a-einuoc.ads)`:
`Ada.Exceptions.Is_Null_Occurrence` (:file:`a-einuoc.ads`)
==========================================================
.. index:: Ada.Exceptions.Is_Null_Occurrence (a-einuoc.ads)
.. index:: Null_Occurrence, testing for
This child subprogram provides a way of testing for the null
exception occurrence (`Null_Occurrence`) without raising
an exception.
.. _`Ada.Exceptions.Last_Chance_Handler_(a-elchha.ads)`:
`Ada.Exceptions.Last_Chance_Handler` (:file:`a-elchha.ads`)
===========================================================
.. index:: Ada.Exceptions.Last_Chance_Handler (a-elchha.ads)
.. index:: Null_Occurrence, testing for
This child subprogram is used for handling otherwise unhandled
exceptions (hence the name last chance), and perform clean ups before
terminating the program. Note that this subprogram never returns.
.. _`Ada.Exceptions.Traceback_(a-exctra.ads)`:
`Ada.Exceptions.Traceback` (:file:`a-exctra.ads`)
=================================================
.. index:: Ada.Exceptions.Traceback (a-exctra.ads)
.. index:: Traceback for Exception Occurrence
This child package provides the subprogram (`Tracebacks`) to
give a traceback array of addresses based on an exception
occurrence.
.. _`Ada.Sequential_IO.C_Streams_(a-siocst.ads)`:
`Ada.Sequential_IO.C_Streams` (:file:`a-siocst.ads`)
====================================================
.. index:: Ada.Sequential_IO.C_Streams (a-siocst.ads)
.. index:: C Streams, Interfacing with Sequential_IO
This package provides subprograms that allow interfacing between
C streams and `Sequential_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Streams.Stream_IO.C_Streams_(a-ssicst.ads)`:
`Ada.Streams.Stream_IO.C_Streams` (:file:`a-ssicst.ads`)
========================================================
.. index:: Ada.Streams.Stream_IO.C_Streams (a-ssicst.ads)
.. index:: C Streams, Interfacing with Stream_IO
This package provides subprograms that allow interfacing between
C streams and `Stream_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Strings.Unbounded.Text_IO_(a-suteio.ads)`:
`Ada.Strings.Unbounded.Text_IO` (:file:`a-suteio.ads`)
======================================================
.. index:: Ada.Strings.Unbounded.Text_IO (a-suteio.ads)
.. index:: Unbounded_String, IO support
.. index:: Text_IO, extensions for unbounded strings
This package provides subprograms for Text_IO for unbounded
strings, avoiding the necessity for an intermediate operation
with ordinary strings.
.. _`Ada.Strings.Wide_Unbounded.Wide_Text_IO_(a-swuwti.ads)`:
`Ada.Strings.Wide_Unbounded.Wide_Text_IO` (:file:`a-swuwti.ads`)
================================================================
.. index:: Ada.Strings.Wide_Unbounded.Wide_Text_IO (a-swuwti.ads)
.. index:: Unbounded_Wide_String, IO support
.. index:: Text_IO, extensions for unbounded wide strings
This package provides subprograms for Text_IO for unbounded
wide strings, avoiding the necessity for an intermediate operation
with ordinary wide strings.
.. _`Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO_(a-szuzti.ads)`:
`Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO` (:file:`a-szuzti.ads`)
==========================================================================
.. index:: Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO (a-szuzti.ads)
.. index:: Unbounded_Wide_Wide_String, IO support
.. index:: Text_IO, extensions for unbounded wide wide strings
This package provides subprograms for Text_IO for unbounded
wide wide strings, avoiding the necessity for an intermediate operation
with ordinary wide wide strings.
.. _`Ada.Text_IO.C_Streams_(a-tiocst.ads)`:
`Ada.Text_IO.C_Streams` (:file:`a-tiocst.ads`)
==============================================
.. index:: Ada.Text_IO.C_Streams (a-tiocst.ads)
.. index:: C Streams, Interfacing with `Text_IO`
This package provides subprograms that allow interfacing between
C streams and `Text_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Text_IO.Reset_Standard_Files_(a-tirsfi.ads)`:
`Ada.Text_IO.Reset_Standard_Files` (:file:`a-tirsfi.ads`)
=========================================================
.. index:: Ada.Text_IO.Reset_Standard_Files (a-tirsfi.ads)
.. index:: Text_IO resetting standard files
This procedure is used to reset the status of the standard files used
by Ada.Text_IO. This is useful in a situation (such as a restart in an
embedded application) where the status of the files may change during
execution (for example a standard input file may be redefined to be
interactive).
.. _`Ada.Wide_Characters.Unicode_(a-wichun.ads)`:
`Ada.Wide_Characters.Unicode` (:file:`a-wichun.ads`)
====================================================
.. index:: Ada.Wide_Characters.Unicode (a-wichun.ads)
.. index:: Unicode categorization, Wide_Character
This package provides subprograms that allow categorization of
Wide_Character values according to Unicode categories.
.. _`Ada.Wide_Text_IO.C_Streams_(a-wtcstr.ads)`:
`Ada.Wide_Text_IO.C_Streams` (:file:`a-wtcstr.ads`)
===================================================
.. index:: Ada.Wide_Text_IO.C_Streams (a-wtcstr.ads)
.. index:: C Streams, Interfacing with `Wide_Text_IO`
This package provides subprograms that allow interfacing between
C streams and `Wide_Text_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Wide_Text_IO.Reset_Standard_Files_(a-wrstfi.ads)`:
`Ada.Wide_Text_IO.Reset_Standard_Files` (:file:`a-wrstfi.ads`)
==============================================================
.. index:: Ada.Wide_Text_IO.Reset_Standard_Files (a-wrstfi.ads)
.. index:: Wide_Text_IO resetting standard files
This procedure is used to reset the status of the standard files used
by Ada.Wide_Text_IO. This is useful in a situation (such as a restart in an
embedded application) where the status of the files may change during
execution (for example a standard input file may be redefined to be
interactive).
.. _`Ada.Wide_Wide_Characters.Unicode_(a-zchuni.ads)`:
`Ada.Wide_Wide_Characters.Unicode` (:file:`a-zchuni.ads`)
=========================================================
.. index:: Ada.Wide_Wide_Characters.Unicode (a-zchuni.ads)
.. index:: Unicode categorization, Wide_Wide_Character
This package provides subprograms that allow categorization of
Wide_Wide_Character values according to Unicode categories.
.. _`Ada.Wide_Wide_Text_IO.C_Streams_(a-ztcstr.ads)`:
`Ada.Wide_Wide_Text_IO.C_Streams` (:file:`a-ztcstr.ads`)
========================================================
.. index:: Ada.Wide_Wide_Text_IO.C_Streams (a-ztcstr.ads)
.. index:: C Streams, Interfacing with `Wide_Wide_Text_IO`
This package provides subprograms that allow interfacing between
C streams and `Wide_Wide_Text_IO`. The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
.. _`Ada.Wide_Wide_Text_IO.Reset_Standard_Files_(a-zrstfi.ads)`:
`Ada.Wide_Wide_Text_IO.Reset_Standard_Files` (:file:`a-zrstfi.ads`)
===================================================================
.. index:: Ada.Wide_Wide_Text_IO.Reset_Standard_Files (a-zrstfi.ads)
.. index:: Wide_Wide_Text_IO resetting standard files
This procedure is used to reset the status of the standard files used
by Ada.Wide_Wide_Text_IO. This is useful in a situation (such as a
restart in an embedded application) where the status of the files may
change during execution (for example a standard input file may be
redefined to be interactive).
.. _`GNAT.Altivec_(g-altive.ads)`:
`GNAT.Altivec` (:file:`g-altive.ads`)
=====================================
.. index:: GNAT.Altivec (g-altive.ads)
.. index:: AltiVec
This is the root package of the GNAT AltiVec binding. It provides
definitions of constants and types common to all the versions of the
binding.
.. _`GNAT.Altivec.Conversions_(g-altcon.ads)`:
`GNAT.Altivec.Conversions` (:file:`g-altcon.ads`)
=================================================
.. index:: GNAT.Altivec.Conversions (g-altcon.ads)
.. index:: AltiVec
This package provides the Vector/View conversion routines.
.. _`GNAT.Altivec.Vector_Operations_(g-alveop.ads)`:
`GNAT.Altivec.Vector_Operations` (:file:`g-alveop.ads`)
=======================================================
.. index:: GNAT.Altivec.Vector_Operations (g-alveop.ads)
.. index:: AltiVec
This package exposes the Ada interface to the AltiVec operations on
vector objects. A soft emulation is included by default in the GNAT
library. The hard binding is provided as a separate package. This unit
is common to both bindings.
.. _`GNAT.Altivec.Vector_Types_(g-alvety.ads)`:
`GNAT.Altivec.Vector_Types` (:file:`g-alvety.ads`)
==================================================
.. index:: GNAT.Altivec.Vector_Types (g-alvety.ads)
.. index:: AltiVec
This package exposes the various vector types part of the Ada binding
to AltiVec facilities.
.. _`GNAT.Altivec.Vector_Views_(g-alvevi.ads)`:
`GNAT.Altivec.Vector_Views` (:file:`g-alvevi.ads`)
==================================================
.. index:: GNAT.Altivec.Vector_Views (g-alvevi.ads)
.. index:: AltiVec
This package provides public 'View' data types from/to which private
vector representations can be converted via
GNAT.Altivec.Conversions. This allows convenient access to individual
vector elements and provides a simple way to initialize vector
objects.
.. _`GNAT.Array_Split_(g-arrspl.ads)`:
`GNAT.Array_Split` (:file:`g-arrspl.ads`)
=========================================
.. index:: GNAT.Array_Split (g-arrspl.ads)
.. index:: Array splitter
Useful array-manipulation routines: given a set of separators, split
an array wherever the separators appear, and provide direct access
to the resulting slices.
.. _`GNAT.AWK_(g-awk.ads)`:
`GNAT.AWK` (:file:`g-awk.ads`)
==============================
.. index:: GNAT.AWK (g-awk.ads)
.. index:: Parsing
.. index:: AWK
Provides AWK-like parsing functions, with an easy interface for parsing one
or more files containing formatted data. The file is viewed as a database
where each record is a line and a field is a data element in this line.
.. _`GNAT.Bounded_Buffers_(g-boubuf.ads)`:
`GNAT.Bounded_Buffers` (:file:`g-boubuf.ads`)
=============================================
.. index:: GNAT.Bounded_Buffers (g-boubuf.ads)
.. index:: Parsing
.. index:: Bounded Buffers
Provides a concurrent generic bounded buffer abstraction. Instances are
useful directly or as parts of the implementations of other abstractions,
such as mailboxes.
.. _`GNAT.Bounded_Mailboxes_(g-boumai.ads)`:
`GNAT.Bounded_Mailboxes` (:file:`g-boumai.ads`)
===============================================
.. index:: GNAT.Bounded_Mailboxes (g-boumai.ads)
.. index:: Parsing
.. index:: Mailboxes
Provides a thread-safe asynchronous intertask mailbox communication facility.
.. _`GNAT.Bubble_Sort_(g-bubsor.ads)`:
`GNAT.Bubble_Sort` (:file:`g-bubsor.ads`)
=========================================
.. index:: GNAT.Bubble_Sort (g-bubsor.ads)
.. index:: Sorting
.. index:: Bubble sort
Provides a general implementation of bubble sort usable for sorting arbitrary
data items. Exchange and comparison procedures are provided by passing
access-to-procedure values.
.. _`GNAT.Bubble_Sort_A_(g-busora.ads)`:
`GNAT.Bubble_Sort_A` (:file:`g-busora.ads`)
===========================================
.. index:: GNAT.Bubble_Sort_A (g-busora.ads)
.. index:: Sorting
.. index:: Bubble sort
Provides a general implementation of bubble sort usable for sorting arbitrary
data items. Move and comparison procedures are provided by passing
access-to-procedure values. This is an older version, retained for
compatibility. Usually `GNAT.Bubble_Sort` will be preferable.
.. _`GNAT.Bubble_Sort_G_(g-busorg.ads)`:
`GNAT.Bubble_Sort_G` (:file:`g-busorg.ads`)
===========================================
.. index:: GNAT.Bubble_Sort_G (g-busorg.ads)
.. index:: Sorting
.. index:: Bubble sort
Similar to `Bubble_Sort_A` except that the move and sorting procedures
are provided as generic parameters, this improves efficiency, especially
if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
.. _`GNAT.Byte_Order_Mark_(g-byorma.ads)`:
`GNAT.Byte_Order_Mark` (:file:`g-byorma.ads`)
=============================================
.. index:: GNAT.Byte_Order_Mark (g-byorma.ads)
.. index:: UTF-8 representation
.. index:: Wide characte representations
Provides a routine which given a string, reads the start of the string to
see whether it is one of the standard byte order marks (BOM's) which signal
the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.
.. _`GNAT.Byte_Swapping_(g-bytswa.ads)`:
`GNAT.Byte_Swapping` (:file:`g-bytswa.ads`)
===========================================
.. index:: GNAT.Byte_Swapping (g-bytswa.ads)
.. index:: Byte swapping
.. index:: Endianness
General routines for swapping the bytes in 2-, 4-, and 8-byte quantities.
Machine-specific implementations are available in some cases.
.. _`GNAT.Calendar_(g-calend.ads)`:
`GNAT.Calendar` (:file:`g-calend.ads`)
======================================
.. index:: GNAT.Calendar (g-calend.ads)
.. index:: Calendar
Extends the facilities provided by `Ada.Calendar` to include handling
of days of the week, an extended `Split` and `Time_Of` capability.
Also provides conversion of `Ada.Calendar.Time` values to and from the
C `timeval` format.
.. _`GNAT.Calendar.Time_IO_(g-catiio.ads)`:
`GNAT.Calendar.Time_IO` (:file:`g-catiio.ads`)
==============================================
.. index:: Calendar
.. index:: Time
.. index:: GNAT.Calendar.Time_IO (g-catiio.ads)
.. _`GNAT.CRC32_(g-crc32.ads)`:
`GNAT.CRC32` (:file:`g-crc32.ads`)
==================================
.. index:: GNAT.CRC32 (g-crc32.ads)
.. index:: CRC32
.. index:: Cyclic Redundancy Check
This package implements the CRC-32 algorithm. For a full description
of this algorithm see
*Computation of Cyclic Redundancy Checks via Table Look-Up*,
:title:`Communications of the ACM`, Vol. 31 No. 8, pp. 1008-1013,
Aug. 1988. Sarwate, D.V.
.. _`GNAT.Case_Util_(g-casuti.ads)`:
`GNAT.Case_Util` (:file:`g-casuti.ads`)
=======================================
.. index:: GNAT.Case_Util (g-casuti.ads)
.. index:: Casing utilities
.. index:: Character handling (`GNAT.Case_Util`)
A set of simple routines for handling upper and lower casing of strings
without the overhead of the full casing tables
in `Ada.Characters.Handling`.
.. _`GNAT.CGI_(g-cgi.ads)`:
`GNAT.CGI` (:file:`g-cgi.ads`)
==============================
.. index:: GNAT.CGI (g-cgi.ads)
.. index:: CGI (Common Gateway Interface)
This is a package for interfacing a GNAT program with a Web server via the
Common Gateway Interface (CGI). Basically this package parses the CGI
parameters, which are a set of key/value pairs sent by the Web server. It
builds a table whose index is the key and provides some services to deal
with this table.
.. _`GNAT.CGI.Cookie_(g-cgicoo.ads)`:
`GNAT.CGI.Cookie` (:file:`g-cgicoo.ads`)
========================================
.. index:: GNAT.CGI.Cookie (g-cgicoo.ads)
.. index:: CGI (Common Gateway Interface) cookie support
.. index:: Cookie support in CGI
This is a package to interface a GNAT program with a Web server via the
Common Gateway Interface (CGI). It exports services to deal with Web
cookies (piece of information kept in the Web client software).
.. _`GNAT.CGI.Debug_(g-cgideb.ads)`:
`GNAT.CGI.Debug` (:file:`g-cgideb.ads`)
=======================================
.. index:: GNAT.CGI.Debug (g-cgideb.ads)
.. index:: CGI (Common Gateway Interface) debugging
This is a package to help debugging CGI (Common Gateway Interface)
programs written in Ada.
.. _`GNAT.Command_Line_(g-comlin.ads)`:
`GNAT.Command_Line` (:file:`g-comlin.ads`)
==========================================
.. index:: GNAT.Command_Line (g-comlin.ads)
.. index:: Command line
Provides a high level interface to `Ada.Command_Line` facilities,
including the ability to scan for named switches with optional parameters
and expand file names using wild card notations.
.. _`GNAT.Compiler_Version_(g-comver.ads)`:
`GNAT.Compiler_Version` (:file:`g-comver.ads`)
==============================================
.. index:: GNAT.Compiler_Version (g-comver.ads)
.. index:: Compiler Version
.. index:: Version, of compiler
Provides a routine for obtaining the version of the compiler used to
compile the program. More accurately this is the version of the binder
used to bind the program (this will normally be the same as the version
of the compiler if a consistent tool set is used to compile all units
of a partition).
.. _`GNAT.Ctrl_C_(g-ctrl_c.ads)`:
`GNAT.Ctrl_C` (:file:`g-ctrl_c.ads`)
====================================
.. index:: GNAT.Ctrl_C (g-ctrl_c.ads)
.. index:: Interrupt
Provides a simple interface to handle Ctrl-C keyboard events.
.. _`GNAT.Current_Exception_(g-curexc.ads)`:
`GNAT.Current_Exception` (:file:`g-curexc.ads`)
===============================================
.. index:: GNAT.Current_Exception (g-curexc.ads)
.. index:: Current exception
.. index:: Exception retrieval
Provides access to information on the current exception that has been raised
without the need for using the Ada 95 / Ada 2005 exception choice parameter
specification syntax.
This is particularly useful in simulating typical facilities for
obtaining information about exceptions provided by Ada 83 compilers.
.. _`GNAT.Debug_Pools_(g-debpoo.ads)`:
`GNAT.Debug_Pools` (:file:`g-debpoo.ads`)
=========================================
.. index:: GNAT.Debug_Pools (g-debpoo.ads)
.. index:: Debugging
.. index:: Debug pools
.. index:: Memory corruption debugging
Provide a debugging storage pools that helps tracking memory corruption
problems.
See `The GNAT Debug_Pool Facility` section in the :title:`GNAT User's Guide`.
.. _`GNAT.Debug_Utilities_(g-debuti.ads)`:
`GNAT.Debug_Utilities` (:file:`g-debuti.ads`)
=============================================
.. index:: GNAT.Debug_Utilities (g-debuti.ads)
.. index:: Debugging
Provides a few useful utilities for debugging purposes, including conversion
to and from string images of address values. Supports both C and Ada formats
for hexadecimal literals.
.. _`GNAT.Decode_String_(g-decstr.ads)`:
`GNAT.Decode_String` (:file:`g-decstr.ads`)
===========================================
.. index:: GNAT.Decode_String (g-decstr.ads)
.. index:: Decoding strings
.. index:: String decoding
.. index:: Wide character encoding
.. index:: UTF-8
.. index:: Unicode
A generic package providing routines for decoding wide character and wide wide
character strings encoded as sequences of 8-bit characters using a specified
encoding method. Includes validation routines, and also routines for stepping
to next or previous encoded character in an encoded string.
Useful in conjunction with Unicode character coding. Note there is a
preinstantiation for UTF-8. See next entry.
.. _`GNAT.Decode_UTF8_String_(g-deutst.ads)`:
`GNAT.Decode_UTF8_String` (:file:`g-deutst.ads`)
================================================
.. index:: GNAT.Decode_UTF8_String (g-deutst.ads)
.. index:: Decoding strings
.. index:: Decoding UTF-8 strings
.. index:: UTF-8 string decoding
.. index:: Wide character decoding
.. index:: UTF-8
.. index:: Unicode
A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding.
.. _`GNAT.Directory_Operations_(g-dirope.ads)`:
`GNAT.Directory_Operations` (:file:`g-dirope.ads`)
==================================================
.. index:: GNAT.Directory_Operations (g-dirope.ads)
.. index:: Directory operations
Provides a set of routines for manipulating directories, including changing
the current directory, making new directories, and scanning the files in a
directory.
.. _`GNAT.Directory_Operations.Iteration_(g-diopit.ads)`:
`GNAT.Directory_Operations.Iteration` (:file:`g-diopit.ads`)
============================================================
.. index:: GNAT.Directory_Operations.Iteration (g-diopit.ads)
.. index:: Directory operations iteration
A child unit of GNAT.Directory_Operations providing additional operations
for iterating through directories.
.. _`GNAT.Dynamic_HTables_(g-dynhta.ads)`:
`GNAT.Dynamic_HTables` (:file:`g-dynhta.ads`)
=============================================
.. index:: GNAT.Dynamic_HTables (g-dynhta.ads)
.. index:: Hash tables
A generic implementation of hash tables that can be used to hash arbitrary
data. Provided in two forms, a simple form with built in hash functions,
and a more complex form in which the hash function is supplied.
This package provides a facility similar to that of `GNAT.HTable`,
except that this package declares a type that can be used to define
dynamic instances of the hash table, while an instantiation of
`GNAT.HTable` creates a single instance of the hash table.
.. _`GNAT.Dynamic_Tables_(g-dyntab.ads)`:
`GNAT.Dynamic_Tables` (:file:`g-dyntab.ads`)
============================================
.. index:: GNAT.Dynamic_Tables (g-dyntab.ads)
.. index:: Table implementation
.. index:: Arrays, extendable
A generic package providing a single dimension array abstraction where the
length of the array can be dynamically modified.
This package provides a facility similar to that of `GNAT.Table`,
except that this package declares a type that can be used to define
dynamic instances of the table, while an instantiation of
`GNAT.Table` creates a single instance of the table type.
.. _`GNAT.Encode_String_(g-encstr.ads)`:
`GNAT.Encode_String` (:file:`g-encstr.ads`)
===========================================
.. index:: GNAT.Encode_String (g-encstr.ads)
.. index:: Encoding strings
.. index:: String encoding
.. index:: Wide character encoding
.. index:: UTF-8
.. index:: Unicode
A generic package providing routines for encoding wide character and wide
wide character strings as sequences of 8-bit characters using a specified
encoding method. Useful in conjunction with Unicode character coding.
Note there is a preinstantiation for UTF-8. See next entry.
.. _`GNAT.Encode_UTF8_String_(g-enutst.ads)`:
`GNAT.Encode_UTF8_String` (:file:`g-enutst.ads`)
================================================
.. index:: GNAT.Encode_UTF8_String (g-enutst.ads)
.. index:: Encoding strings
.. index:: Encoding UTF-8 strings
.. index:: UTF-8 string encoding
.. index:: Wide character encoding
.. index:: UTF-8
.. index:: Unicode
A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding.
.. _`GNAT.Exception_Actions_(g-excact.ads)`:
`GNAT.Exception_Actions` (:file:`g-excact.ads`)
===============================================
.. index:: GNAT.Exception_Actions (g-excact.ads)
.. index:: Exception actions
Provides callbacks when an exception is raised. Callbacks can be registered
for specific exceptions, or when any exception is raised. This
can be used for instance to force a core dump to ease debugging.
.. _`GNAT.Exception_Traces_(g-exctra.ads)`:
`GNAT.Exception_Traces` (:file:`g-exctra.ads`)
==============================================
.. index:: GNAT.Exception_Traces (g-exctra.ads)
.. index:: Exception traces
.. index:: Debugging
Provides an interface allowing to control automatic output upon exception
occurrences.
.. _`GNAT.Exceptions_(g-expect.ads)`:
`GNAT.Exceptions` (:file:`g-expect.ads`)
========================================
.. index:: GNAT.Exceptions (g-expect.ads)
.. index:: Exceptions, Pure
.. index:: Pure packages, exceptions
Normally it is not possible to raise an exception with
a message from a subprogram in a pure package, since the
necessary types and subprograms are in `Ada.Exceptions`
which is not a pure unit. `GNAT.Exceptions` provides a
facility for getting around this limitation for a few
predefined exceptions, and for example allow raising
`Constraint_Error` with a message from a pure subprogram.
.. _`GNAT.Expect_(g-expect.ads)`:
`GNAT.Expect` (:file:`g-expect.ads`)
====================================
.. index:: GNAT.Expect (g-expect.ads)
Provides a set of subprograms similar to what is available
with the standard Tcl Expect tool.
It allows you to easily spawn and communicate with an external process.
You can send commands or inputs to the process, and compare the output
with some expected regular expression. Currently `GNAT.Expect`
is implemented on all native GNAT ports.
It is not implemented for cross ports, and in particular is not
implemented for VxWorks or LynxOS.
.. _`GNAT.Expect.TTY_(g-exptty.ads)`:
`GNAT.Expect.TTY` (:file:`g-exptty.ads`)
========================================
.. index:: GNAT.Expect.TTY (g-exptty.ads)
As GNAT.Expect but using pseudo-terminal.
Currently `GNAT.Expect.TTY` is implemented on all native GNAT
ports. It is not implemented for cross ports, and
in particular is not implemented for VxWorks or LynxOS.
.. _`GNAT.Float_Control_(g-flocon.ads)`:
`GNAT.Float_Control` (:file:`g-flocon.ads`)
===========================================
.. index:: GNAT.Float_Control (g-flocon.ads)
.. index:: Floating-Point Processor
Provides an interface for resetting the floating-point processor into the
mode required for correct semantic operation in Ada. Some third party
library calls may cause this mode to be modified, and the Reset procedure
in this package can be used to reestablish the required mode.
.. _`GNAT.Formatted_String_(g-forstr.ads)`:
`GNAT.Formatted_String` (:file:`g-forstr.ads`)
==============================================
.. index:: GNAT.Formatted_String (g-forstr.ads)
.. index:: Formatted String
Provides support for C/C++ printf() formatted strings. The format is
copied from the printf() routine and should therefore gives identical
output. Some generic routines are provided to be able to use types
derived from Integer, Float or enumerations as values for the
formatted string.
.. _`GNAT.Heap_Sort_(g-heasor.ads)`:
`GNAT.Heap_Sort` (:file:`g-heasor.ads`)
=======================================
.. index:: GNAT.Heap_Sort (g-heasor.ads)
.. index:: Sorting
Provides a general implementation of heap sort usable for sorting arbitrary
data items. Exchange and comparison procedures are provided by passing
access-to-procedure values. The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
.. _`GNAT.Heap_Sort_A_(g-hesora.ads)`:
`GNAT.Heap_Sort_A` (:file:`g-hesora.ads`)
=========================================
.. index:: GNAT.Heap_Sort_A (g-hesora.ads)
.. index:: Sorting
Provides a general implementation of heap sort usable for sorting arbitrary
data items. Move and comparison procedures are provided by passing
access-to-procedure values. The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
This differs from `GNAT.Heap_Sort` in having a less convenient
interface, but may be slightly more efficient.
.. _`GNAT.Heap_Sort_G_(g-hesorg.ads)`:
`GNAT.Heap_Sort_G` (:file:`g-hesorg.ads`)
=========================================
.. index:: GNAT.Heap_Sort_G (g-hesorg.ads)
.. index:: Sorting
Similar to `Heap_Sort_A` except that the move and sorting procedures
are provided as generic parameters, this improves efficiency, especially
if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
.. _`GNAT.HTable_(g-htable.ads)`:
`GNAT.HTable` (:file:`g-htable.ads`)
====================================
.. index:: GNAT.HTable (g-htable.ads)
.. index:: Hash tables
A generic implementation of hash tables that can be used to hash arbitrary
data. Provides two approaches, one a simple static approach, and the other
allowing arbitrary dynamic hash tables.
.. _`GNAT.IO_(g-io.ads)`:
`GNAT.IO` (:file:`g-io.ads`)
============================
.. index:: GNAT.IO (g-io.ads)
.. index:: Simple I/O
.. index:: Input/Output facilities
A simple preelaborable input-output package that provides a subset of
simple Text_IO functions for reading characters and strings from
Standard_Input, and writing characters, strings and integers to either
Standard_Output or Standard_Error.
.. _`GNAT.IO_Aux_(g-io_aux.ads)`:
`GNAT.IO_Aux` (:file:`g-io_aux.ads`)
====================================
.. index:: GNAT.IO_Aux (g-io_aux.ads)
.. index:: Text_IO
.. index:: Input/Output facilities
Provides some auxiliary functions for use with Text_IO, including a test
for whether a file exists, and functions for reading a line of text.
.. _`GNAT.Lock_Files_(g-locfil.ads)`:
`GNAT.Lock_Files` (:file:`g-locfil.ads`)
========================================
.. index:: GNAT.Lock_Files (g-locfil.ads)
.. index:: File locking
.. index:: Locking using files
Provides a general interface for using files as locks. Can be used for
providing program level synchronization.
.. _`GNAT.MBBS_Discrete_Random_(g-mbdira.ads)`:
`GNAT.MBBS_Discrete_Random` (:file:`g-mbdira.ads`)
==================================================
.. index:: GNAT.MBBS_Discrete_Random (g-mbdira.ads)
.. index:: Random number generation
The original implementation of `Ada.Numerics.Discrete_Random`. Uses
a modified version of the Blum-Blum-Shub generator.
.. _`GNAT.MBBS_Float_Random_(g-mbflra.ads)`:
`GNAT.MBBS_Float_Random` (:file:`g-mbflra.ads`)
===============================================
.. index:: GNAT.MBBS_Float_Random (g-mbflra.ads)
.. index:: Random number generation
The original implementation of `Ada.Numerics.Float_Random`. Uses
a modified version of the Blum-Blum-Shub generator.
.. _`GNAT.MD5_(g-md5.ads)`:
`GNAT.MD5` (:file:`g-md5.ads`)
==============================
.. index:: GNAT.MD5 (g-md5.ads)
.. index:: Message Digest MD5
Implements the MD5 Message-Digest Algorithm as described in RFC 1321, and
the HMAC-MD5 message authentication function as described in RFC 2104 and
FIPS PUB 198.
.. _`GNAT.Memory_Dump_(g-memdum.ads)`:
`GNAT.Memory_Dump` (:file:`g-memdum.ads`)
=========================================
.. index:: GNAT.Memory_Dump (g-memdum.ads)
.. index:: Dump Memory
Provides a convenient routine for dumping raw memory to either the
standard output or standard error files. Uses GNAT.IO for actual
output.
.. _`GNAT.Most_Recent_Exception_(g-moreex.ads)`:
`GNAT.Most_Recent_Exception` (:file:`g-moreex.ads`)
===================================================
.. index:: GNAT.Most_Recent_Exception (g-moreex.ads)
.. index:: Exception, obtaining most recent
Provides access to the most recently raised exception. Can be used for
various logging purposes, including duplicating functionality of some
Ada 83 implementation dependent extensions.
.. _`GNAT.OS_Lib_(g-os_lib.ads)`:
`GNAT.OS_Lib` (:file:`g-os_lib.ads`)
====================================
.. index:: GNAT.OS_Lib (g-os_lib.ads)
.. index:: Operating System interface
.. index:: Spawn capability
Provides a range of target independent operating system interface functions,
including time/date management, file operations, subprocess management,
including a portable spawn procedure, and access to environment variables
and error return codes.
.. _`GNAT.Perfect_Hash_Generators_(g-pehage.ads)`:
`GNAT.Perfect_Hash_Generators` (:file:`g-pehage.ads`)
=====================================================
.. index:: GNAT.Perfect_Hash_Generators (g-pehage.ads)
.. index:: Hash functions
Provides a generator of static minimal perfect hash functions. No
collisions occur and each item can be retrieved from the table in one
probe (perfect property). The hash table size corresponds to the exact
size of the key set and no larger (minimal property). The key set has to
be know in advance (static property). The hash functions are also order
preserving. If w2 is inserted after w1 in the generator, their
hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
.. _`GNAT.Random_Numbers_(g-rannum.ads)`:
`GNAT.Random_Numbers` (:file:`g-rannum.ads`)
============================================
.. index:: GNAT.Random_Numbers (g-rannum.ads)
.. index:: Random number generation
Provides random number capabilities which extend those available in the
standard Ada library and are more convenient to use.
.. _`GNAT.Regexp_(g-regexp.ads)`:
`GNAT.Regexp` (:file:`g-regexp.ads`)
====================================
.. index:: GNAT.Regexp (g-regexp.ads)
.. index:: Regular expressions
.. index:: Pattern matching
A simple implementation of regular expressions, using a subset of regular
expression syntax copied from familiar Unix style utilities. This is the
simplest of the three pattern matching packages provided, and is particularly
suitable for 'file globbing' applications.
.. _`GNAT.Registry_(g-regist.ads)`:
`GNAT.Registry` (:file:`g-regist.ads`)
======================================
.. index:: GNAT.Registry (g-regist.ads)
.. index:: Windows Registry
This is a high level binding to the Windows registry. It is possible to
do simple things like reading a key value, creating a new key. For full
registry API, but at a lower level of abstraction, refer to the Win32.Winreg
package provided with the Win32Ada binding
.. _`GNAT.Regpat_(g-regpat.ads)`:
`GNAT.Regpat` (:file:`g-regpat.ads`)
====================================
.. index:: GNAT.Regpat (g-regpat.ads)
.. index:: Regular expressions
.. index:: Pattern matching
A complete implementation of Unix-style regular expression matching, copied
from the original V7 style regular expression library written in C by
Henry Spencer (and binary compatible with this C library).
.. _`GNAT.Rewrite_Data_(g-rewdat.ads)`:
`GNAT.Rewrite_Data` (:file:`g-rewdat.ads`)
==========================================
.. index:: GNAT.Rewrite_Data (g-rewdat.ads)
.. index:: Rewrite data
A unit to rewrite on-the-fly string occurrences in a stream of
data. The implementation has a very minimal memory footprint as the
full content to be processed is not loaded into memory all at once. This makes
this interface usable for large files or socket streams.
.. _`GNAT.Secondary_Stack_Info_(g-sestin.ads)`:
`GNAT.Secondary_Stack_Info` (:file:`g-sestin.ads`)
==================================================
.. index:: GNAT.Secondary_Stack_Info (g-sestin.ads)
.. index:: Secondary Stack Info
Provide the capability to query the high water mark of the current task's
secondary stack.
.. _`GNAT.Semaphores_(g-semaph.ads)`:
`GNAT.Semaphores` (:file:`g-semaph.ads`)
========================================
.. index:: GNAT.Semaphores (g-semaph.ads)
.. index:: Semaphores
Provides classic counting and binary semaphores using protected types.
.. _`GNAT.Serial_Communications_(g-sercom.ads)`:
`GNAT.Serial_Communications` (:file:`g-sercom.ads`)
===================================================
.. index:: GNAT.Serial_Communications (g-sercom.ads)
.. index:: Serial_Communications
Provides a simple interface to send and receive data over a serial
port. This is only supported on GNU/Linux and Windows.
.. _`GNAT.SHA1_(g-sha1.ads)`:
`GNAT.SHA1` (:file:`g-sha1.ads`)
================================
.. index:: GNAT.SHA1 (g-sha1.ads)
.. index:: Secure Hash Algorithm SHA-1
Implements the SHA-1 Secure Hash Algorithm as described in FIPS PUB 180-3
and RFC 3174, and the HMAC-SHA1 message authentication function as described
in RFC 2104 and FIPS PUB 198.
.. _`GNAT.SHA224_(g-sha224.ads)`:
`GNAT.SHA224` (:file:`g-sha224.ads`)
====================================
.. index:: GNAT.SHA224 (g-sha224.ads)
.. index:: Secure Hash Algorithm SHA-224
Implements the SHA-224 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA224 message authentication function as described
in RFC 2104 and FIPS PUB 198.
.. _`GNAT.SHA256_(g-sha256.ads)`:
`GNAT.SHA256` (:file:`g-sha256.ads`)
====================================
.. index:: GNAT.SHA256 (g-sha256.ads)
.. index:: Secure Hash Algorithm SHA-256
Implements the SHA-256 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA256 message authentication function as described
in RFC 2104 and FIPS PUB 198.
.. _`GNAT.SHA384_(g-sha384.ads)`:
`GNAT.SHA384` (:file:`g-sha384.ads`)
====================================
.. index:: GNAT.SHA384 (g-sha384.ads)
.. index:: Secure Hash Algorithm SHA-384
Implements the SHA-384 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA384 message authentication function as described
in RFC 2104 and FIPS PUB 198.
.. _`GNAT.SHA512_(g-sha512.ads)`:
`GNAT.SHA512` (:file:`g-sha512.ads`)
====================================
.. index:: GNAT.SHA512 (g-sha512.ads)
.. index:: Secure Hash Algorithm SHA-512
Implements the SHA-512 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA512 message authentication function as described
in RFC 2104 and FIPS PUB 198.
.. _`GNAT.Signals_(g-signal.ads)`:
`GNAT.Signals` (:file:`g-signal.ads`)
=====================================
.. index:: GNAT.Signals (g-signal.ads)
.. index:: Signals
Provides the ability to manipulate the blocked status of signals on supported
targets.
.. _`GNAT.Sockets_(g-socket.ads)`:
`GNAT.Sockets` (:file:`g-socket.ads`)
=====================================
.. index:: GNAT.Sockets (g-socket.ads)
.. index:: Sockets
A high level and portable interface to develop sockets based applications.
This package is based on the sockets thin binding found in
`GNAT.Sockets.Thin`. Currently `GNAT.Sockets` is implemented
on all native GNAT ports and on VxWorks cross prots. It is not implemented for
the LynxOS cross port.
.. _`GNAT.Source_Info_(g-souinf.ads)`:
`GNAT.Source_Info` (:file:`g-souinf.ads`)
=========================================
.. index:: GNAT.Source_Info (g-souinf.ads)
.. index:: Source Information
Provides subprograms that give access to source code information known at
compile time, such as the current file name and line number. Also provides
subprograms yielding the date and time of the current compilation (like the
C macros `__DATE__` and `__TIME__`)
.. _`GNAT.Spelling_Checker_(g-speche.ads)`:
`GNAT.Spelling_Checker` (:file:`g-speche.ads`)
==============================================
.. index:: GNAT.Spelling_Checker (g-speche.ads)
.. index:: Spell checking
Provides a function for determining whether one string is a plausible
near misspelling of another string.
.. _`GNAT.Spelling_Checker_Generic_(g-spchge.ads)`:
`GNAT.Spelling_Checker_Generic` (:file:`g-spchge.ads`)
======================================================
.. index:: GNAT.Spelling_Checker_Generic (g-spchge.ads)
.. index:: Spell checking
Provides a generic function that can be instantiated with a string type for
determining whether one string is a plausible near misspelling of another
string.
.. _`GNAT.Spitbol.Patterns_(g-spipat.ads)`:
`GNAT.Spitbol.Patterns` (:file:`g-spipat.ads`)
==============================================
.. index:: GNAT.Spitbol.Patterns (g-spipat.ads)
.. index:: SPITBOL pattern matching
.. index:: Pattern matching
A complete implementation of SNOBOL4 style pattern matching. This is the
most elaborate of the pattern matching packages provided. It fully duplicates
the SNOBOL4 dynamic pattern construction and matching capabilities, using the
efficient algorithm developed by Robert Dewar for the SPITBOL system.
.. _`GNAT.Spitbol_(g-spitbo.ads)`:
`GNAT.Spitbol` (:file:`g-spitbo.ads`)
=====================================
.. index:: GNAT.Spitbol (g-spitbo.ads)
.. index:: SPITBOL interface
The top level package of the collection of SPITBOL-style functionality, this
package provides basic SNOBOL4 string manipulation functions, such as
Pad, Reverse, Trim, Substr capability, as well as a generic table function
useful for constructing arbitrary mappings from strings in the style of
the SNOBOL4 TABLE function.
.. _`GNAT.Spitbol.Table_Boolean_(g-sptabo.ads)`:
`GNAT.Spitbol.Table_Boolean` (:file:`g-sptabo.ads`)
===================================================
.. index:: GNAT.Spitbol.Table_Boolean (g-sptabo.ads)
.. index:: Sets of strings
.. index:: SPITBOL Tables
A library level of instantiation of `GNAT.Spitbol.Patterns.Table`
for type `Standard.Boolean`, giving an implementation of sets of
string values.
.. _`GNAT.Spitbol.Table_Integer_(g-sptain.ads)`:
`GNAT.Spitbol.Table_Integer` (:file:`g-sptain.ads`)
===================================================
.. index:: GNAT.Spitbol.Table_Integer (g-sptain.ads)
.. index:: Integer maps
.. index:: Maps
.. index:: SPITBOL Tables
A library level of instantiation of `GNAT.Spitbol.Patterns.Table`
for type `Standard.Integer`, giving an implementation of maps
from string to integer values.
.. _`GNAT.Spitbol.Table_VString_(g-sptavs.ads)`:
`GNAT.Spitbol.Table_VString` (:file:`g-sptavs.ads`)
===================================================
.. index:: GNAT.Spitbol.Table_VString (g-sptavs.ads)
.. index:: String maps
.. index:: Maps
.. index:: SPITBOL Tables
A library level of instantiation of `GNAT.Spitbol.Patterns.Table` for
a variable length string type, giving an implementation of general
maps from strings to strings.
.. _`GNAT.SSE_(g-sse.ads)`:
`GNAT.SSE` (:file:`g-sse.ads`)
==============================
.. index:: GNAT.SSE (g-sse.ads)
Root of a set of units aimed at offering Ada bindings to a subset of
the Intel(r) Streaming SIMD Extensions with GNAT on the x86 family of
targets. It exposes vector component types together with a general
introduction to the binding contents and use.
.. _`GNAT.SSE.Vector_Types_(g-ssvety.ads)`:
`GNAT.SSE.Vector_Types` (:file:`g-ssvety.ads`)
==============================================
.. index:: GNAT.SSE.Vector_Types (g-ssvety.ads)
SSE vector types for use with SSE related intrinsics.
.. _`GNAT.Strings_(g-string.ads)`:
`GNAT.Strings` (:file:`g-string.ads`)
=====================================
.. index:: GNAT.Strings (g-string.ads)
Common String access types and related subprograms. Basically it
defines a string access and an array of string access types.
.. _`GNAT.String_Split_(g-strspl.ads)`:
`GNAT.String_Split` (:file:`g-strspl.ads`)
==========================================
.. index:: GNAT.String_Split (g-strspl.ads)
.. index:: String splitter
Useful string manipulation routines: given a set of separators, split
a string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
`GNAT.Array_Split`.
.. _`GNAT.Table_(g-table.ads)`:
`GNAT.Table` (:file:`g-table.ads`)
==================================
.. index:: GNAT.Table (g-table.ads)
.. index:: Table implementation
.. index:: Arrays, extendable
A generic package providing a single dimension array abstraction where the
length of the array can be dynamically modified.
This package provides a facility similar to that of `GNAT.Dynamic_Tables`,
except that this package declares a single instance of the table type,
while an instantiation of `GNAT.Dynamic_Tables` creates a type that can be
used to define dynamic instances of the table.
.. _`GNAT.Task_Lock_(g-tasloc.ads)`:
`GNAT.Task_Lock` (:file:`g-tasloc.ads`)
=======================================
.. index:: GNAT.Task_Lock (g-tasloc.ads)
.. index:: Task synchronization
.. index:: Task locking
.. index:: Locking
A very simple facility for locking and unlocking sections of code using a
single global task lock. Appropriate for use in situations where contention
between tasks is very rarely expected.
.. _`GNAT.Time_Stamp_(g-timsta.ads)`:
`GNAT.Time_Stamp` (:file:`g-timsta.ads`)
========================================
.. index:: GNAT.Time_Stamp (g-timsta.ads)
.. index:: Time stamp
.. index:: Current time
Provides a simple function that returns a string YYYY-MM-DD HH:MM:SS.SS that
represents the current date and time in ISO 8601 format. This is a very simple
routine with minimal code and there are no dependencies on any other unit.
.. _`GNAT.Threads_(g-thread.ads)`:
`GNAT.Threads` (:file:`g-thread.ads`)
=====================================
.. index:: GNAT.Threads (g-thread.ads)
.. index:: Foreign threads
.. index:: Threads, foreign
Provides facilities for dealing with foreign threads which need to be known
by the GNAT run-time system. Consult the documentation of this package for
further details if your program has threads that are created by a non-Ada
environment which then accesses Ada code.
.. _`GNAT.Traceback_(g-traceb.ads)`:
`GNAT.Traceback` (:file:`g-traceb.ads`)
=======================================
.. index:: GNAT.Traceback (g-traceb.ads)
.. index:: Trace back facilities
Provides a facility for obtaining non-symbolic traceback information, useful
in various debugging situations.
.. _`GNAT.Traceback.Symbolic_(g-trasym.ads)`:
`GNAT.Traceback.Symbolic` (:file:`g-trasym.ads`)
================================================
.. index:: GNAT.Traceback.Symbolic (g-trasym.ads)
.. index:: Trace back facilities
.. _`GNAT.UTF_32_(g-table.ads)`:
`GNAT.UTF_32` (:file:`g-table.ads`)
===================================
.. index:: GNAT.UTF_32 (g-table.ads)
.. index:: Wide character codes
This is a package intended to be used in conjunction with the
`Wide_Character` type in Ada 95 and the
`Wide_Wide_Character` type in Ada 2005 (available
in `GNAT` in Ada 2005 mode). This package contains
Unicode categorization routines, as well as lexical
categorization routines corresponding to the Ada 2005
lexical rules for identifiers and strings, and also a
lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
.. _`GNAT.Wide_Spelling_Checker_(g-u3spch.ads)`:
`GNAT.Wide_Spelling_Checker` (:file:`g-u3spch.ads`)
===================================================
.. index:: GNAT.Wide_Spelling_Checker (g-u3spch.ads)
.. index:: Spell checking
Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.
.. _`GNAT.Wide_Spelling_Checker_(g-wispch.ads)`:
`GNAT.Wide_Spelling_Checker` (:file:`g-wispch.ads`)
===================================================
.. index:: GNAT.Wide_Spelling_Checker (g-wispch.ads)
.. index:: Spell checking
Provides a function for determining whether one wide string is a plausible
near misspelling of another wide string.
.. _`GNAT.Wide_String_Split_(g-wistsp.ads)`:
`GNAT.Wide_String_Split` (:file:`g-wistsp.ads`)
===============================================
.. index:: GNAT.Wide_String_Split (g-wistsp.ads)
.. index:: Wide_String splitter
Useful wide string manipulation routines: given a set of separators, split
a wide string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
`GNAT.Array_Split`.
.. _`GNAT.Wide_Wide_Spelling_Checker_(g-zspche.ads)`:
`GNAT.Wide_Wide_Spelling_Checker` (:file:`g-zspche.ads`)
========================================================
.. index:: GNAT.Wide_Wide_Spelling_Checker (g-zspche.ads)
.. index:: Spell checking
Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string.
.. _`GNAT.Wide_Wide_String_Split_(g-zistsp.ads)`:
`GNAT.Wide_Wide_String_Split` (:file:`g-zistsp.ads`)
====================================================
.. index:: GNAT.Wide_Wide_String_Split (g-zistsp.ads)
.. index:: Wide_Wide_String splitter
Useful wide wide string manipulation routines: given a set of separators, split
a wide wide string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
`GNAT.Array_Split`.
.. _`Interfaces.C.Extensions_(i-cexten.ads)`:
`Interfaces.C.Extensions` (:file:`i-cexten.ads`)
================================================
.. index:: Interfaces.C.Extensions (i-cexten.ads)
This package contains additional C-related definitions, intended
for use with either manually or automatically generated bindings
to C libraries.
.. _`Interfaces.C.Streams_(i-cstrea.ads)`:
`Interfaces.C.Streams` (:file:`i-cstrea.ads`)
=============================================
.. index:: Interfaces.C.Streams (i-cstrea.ads)
.. index:: C streams, interfacing
This package is a binding for the most commonly used operations
on C streams.
.. _`Interfaces.Packed_Decimal_(i-pacdec.ads)`:
`Interfaces.Packed_Decimal` (:file:`i-pacdec.ads`)
==================================================
.. index:: Interfaces.Packed_Decimal (i-pacdec.ads)
.. index:: IBM Packed Format
.. index:: Packed Decimal
This package provides a set of routines for conversions to and
from a packed decimal format compatible with that used on IBM
mainframes.
.. _`Interfaces.VxWorks_(i-vxwork.ads)`:
`Interfaces.VxWorks` (:file:`i-vxwork.ads`)
===========================================
.. index:: Interfaces.VxWorks (i-vxwork.ads)
.. index:: Interfacing to VxWorks
.. index:: VxWorks, interfacing
This package provides a limited binding to the VxWorks API.
In particular, it interfaces with the
VxWorks hardware interrupt facilities.
.. _`Interfaces.VxWorks.IO_(i-vxwoio.ads)`:
`Interfaces.VxWorks.IO` (:file:`i-vxwoio.ads`)
==============================================
.. index:: Interfaces.VxWorks.IO (i-vxwoio.ads)
.. index:: Interfacing to VxWorks' I/O
.. index:: VxWorks, I/O interfacing
.. index:: VxWorks, Get_Immediate
.. index:: Get_Immediate, VxWorks
This package provides a binding to the ioctl (IO/Control)
function of VxWorks, defining a set of option values and
function codes. A particular use of this package is
to enable the use of Get_Immediate under VxWorks.
.. _`System.Address_Image_(s-addima.ads)`:
`System.Address_Image` (:file:`s-addima.ads`)
=============================================
.. index:: System.Address_Image (s-addima.ads)
.. index:: Address image
.. index:: Image, of an address
This function provides a useful debugging
function that gives an (implementation dependent)
string which identifies an address.
.. _`System.Assertions_(s-assert.ads)`:
`System.Assertions` (:file:`s-assert.ads`)
==========================================
.. index:: System.Assertions (s-assert.ads)
.. index:: Assertions
.. index:: Assert_Failure, exception
This package provides the declaration of the exception raised
by an run-time assertion failure, as well as the routine that
is used internally to raise this assertion.
.. _`System.Atomic_Counters_(s-atocou.ads)`:
`System.Atomic_Counters` (:file:`s-atocou.ads`)
===============================================
.. index:: System.Atomic_Counters (s-atocou.ads)
This package provides the declaration of an atomic counter type,
together with efficient routines (using hardware
synchronization primitives) for incrementing, decrementing,
and testing of these counters. This package is implemented
on most targets, including all Alpha, ia64, PowerPC, SPARC V9,
x86, and x86_64 platforms.
.. _`System.Memory_(s-memory.ads)`:
`System.Memory` (:file:`s-memory.ads`)
======================================
.. index:: System.Memory (s-memory.ads)
.. index:: Memory allocation
This package provides the interface to the low level routines used
by the generated code for allocation and freeing storage for the
default storage pool (analogous to the C routines malloc and free.
It also provides a reallocation interface analogous to the C routine
realloc. The body of this unit may be modified to provide alternative
allocation mechanisms for the default pool, and in addition, direct
calls to this unit may be made for low level allocation uses (for
example see the body of `GNAT.Tables`).
.. _`System.Multiprocessors_(s-multip.ads)`:
`System.Multiprocessors` (:file:`s-multip.ads`)
===============================================
.. index:: System.Multiprocessors (s-multip.ads)
.. index:: Multiprocessor interface
This is an Ada 2012 unit defined in the Ada 2012 Reference Manual, but
in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
.. _`System.Multiprocessors.Dispatching_Domains_(s-mudido.ads)`:
`System.Multiprocessors.Dispatching_Domains` (:file:`s-mudido.ads`)
===================================================================
.. index:: System.Multiprocessors.Dispatching_Domains (s-mudido.ads)
.. index:: Multiprocessor interface
This is an Ada 2012 unit defined in the Ada 2012 Reference Manual, but
in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
.. _`System.Partition_Interface_(s-parint.ads)`:
`System.Partition_Interface` (:file:`s-parint.ads`)
===================================================
.. index:: System.Partition_Interface (s-parint.ads)
.. index:: Partition interfacing functions
This package provides facilities for partition interfacing. It
is used primarily in a distribution context when using Annex E
with `GLADE`.
.. _`System.Pool_Global_(s-pooglo.ads)`:
`System.Pool_Global` (:file:`s-pooglo.ads`)
===========================================
.. index:: System.Pool_Global (s-pooglo.ads)
.. index:: Storage pool, global
.. index:: Global storage pool
This package provides a storage pool that is equivalent to the default
storage pool used for access types for which no pool is specifically
declared. It uses malloc/free to allocate/free and does not attempt to
do any automatic reclamation.
.. _`System.Pool_Local_(s-pooloc.ads)`:
`System.Pool_Local` (:file:`s-pooloc.ads`)
==========================================
.. index:: System.Pool_Local (s-pooloc.ads)
.. index:: Storage pool, local
.. index:: Local storage pool
This package provides a storage pool that is intended for use with locally
defined access types. It uses malloc/free for allocate/free, and maintains
a list of allocated blocks, so that all storage allocated for the pool can
be freed automatically when the pool is finalized.
.. _`System.Restrictions_(s-restri.ads)`:
`System.Restrictions` (:file:`s-restri.ads`)
============================================
.. index:: System.Restrictions (s-restri.ads)
.. index:: Run-time restrictions access
This package provides facilities for accessing at run time
the status of restrictions specified at compile time for
the partition. Information is available both with regard
to actual restrictions specified, and with regard to
compiler determined information on which restrictions
are violated by one or more packages in the partition.
.. _`System.Rident_(s-rident.ads)`:
`System.Rident` (:file:`s-rident.ads`)
======================================
.. index:: System.Rident (s-rident.ads)
.. index:: Restrictions definitions
This package provides definitions of the restrictions
identifiers supported by GNAT, and also the format of
the restrictions provided in package System.Restrictions.
It is not normally necessary to `with` this generic package
since the necessary instantiation is included in
package System.Restrictions.
.. _`System.Strings.Stream_Ops_(s-ststop.ads)`:
`System.Strings.Stream_Ops` (:file:`s-ststop.ads`)
==================================================
.. index:: System.Strings.Stream_Ops (s-ststop.ads)
.. index:: Stream operations
.. index:: String stream operations
This package provides a set of stream subprograms for standard string types.
It is intended primarily to support implicit use of such subprograms when
stream attributes are applied to string types, but the subprograms in this
package can be used directly by application programs.
.. _`System.Unsigned_Types_(s-unstyp.ads)`:
`System.Unsigned_Types` (:file:`s-unstyp.ads`)
==============================================
.. index:: System.Unsigned_Types (s-unstyp.ads)
This package contains definitions of standard unsigned types that
correspond in size to the standard signed types declared in Standard,
and (unlike the types in Interfaces) have corresponding names. It
also contains some related definitions for other specialized types
used by the compiler in connection with packed array types.
.. _`System.Wch_Cnv_(s-wchcnv.ads)`:
`System.Wch_Cnv` (:file:`s-wchcnv.ads`)
=======================================
.. index:: System.Wch_Cnv (s-wchcnv.ads)
.. index:: Wide Character, Representation
.. index:: Wide String, Conversion
.. index:: Representation of wide characters
This package provides routines for converting between
wide and wide wide characters and a representation as a value of type
`Standard.String`, using a specified wide character
encoding method. It uses definitions in
package `System.Wch_Con`.
.. _`System.Wch_Con_(s-wchcon.ads)`:
`System.Wch_Con` (:file:`s-wchcon.ads`)
=======================================
.. index:: System.Wch_Con (s-wchcon.ads)
This package provides definitions and descriptions of
the various methods used for encoding wide characters
in ordinary strings. These definitions are used by
the package `System.Wch_Cnv`.
.. _The_Implementation_of_Standard_I/O:
**********************************
The Implementation of Standard I/O
**********************************
GNAT implements all the required input-output facilities described in
A.6 through A.14. These sections of the Ada Reference Manual describe the
required behavior of these packages from the Ada point of view, and if
you are writing a portable Ada program that does not need to know the
exact manner in which Ada maps to the outside world when it comes to
reading or writing external files, then you do not need to read this
chapter. As long as your files are all regular files (not pipes or
devices), and as long as you write and read the files only from Ada, the
description in the Ada Reference Manual is sufficient.
However, if you want to do input-output to pipes or other devices, such
as the keyboard or screen, or if the files you are dealing with are
either generated by some other language, or to be read by some other
language, then you need to know more about the details of how the GNAT
implementation of these input-output facilities behaves.
In this chapter we give a detailed description of exactly how GNAT
interfaces to the file system. As always, the sources of the system are
available to you for answering questions at an even more detailed level,
but for most purposes the information in this chapter will suffice.
Another reason that you may need to know more about how input-output is
implemented arises when you have a program written in mixed languages
where, for example, files are shared between the C and Ada sections of
the same program. GNAT provides some additional facilities, in the form
of additional child library packages, that facilitate this sharing, and
these additional facilities are also described in this chapter.
.. _Standard_I/O_Packages:
Standard I/O Packages
=====================
The Standard I/O packages described in Annex A for
*
Ada.Text_IO
*
Ada.Text_IO.Complex_IO
*
Ada.Text_IO.Text_Streams
*
Ada.Wide_Text_IO
*
Ada.Wide_Text_IO.Complex_IO
*
Ada.Wide_Text_IO.Text_Streams
*
Ada.Wide_Wide_Text_IO
*
Ada.Wide_Wide_Text_IO.Complex_IO
*
Ada.Wide_Wide_Text_IO.Text_Streams
*
Ada.Stream_IO
*
Ada.Sequential_IO
*
Ada.Direct_IO
are implemented using the C
library streams facility; where
*
All files are opened using `fopen`.
*
All input/output operations use `fread`/`fwrite`.
There is no internal buffering of any kind at the Ada library level. The only
buffering is that provided at the system level in the implementation of the
library routines that support streams. This facilitates shared use of these
streams by mixed language programs. Note though that system level buffering is
explicitly enabled at elaboration of the standard I/O packages and that can
have an impact on mixed language programs, in particular those using I/O before
calling the Ada elaboration routine (e.g., adainit). It is recommended to call
the Ada elaboration routine before performing any I/O or when impractical,
flush the common I/O streams and in particular Standard_Output before
elaborating the Ada code.
.. _FORM_Strings:
FORM Strings
============
The format of a FORM string in GNAT is:
::
"keyword=value,keyword=value,...,keyword=value"
where letters may be in upper or lower case, and there are no spaces
between values. The order of the entries is not important. Currently
the following keywords defined.
::
TEXT_TRANSLATION=[YES|NO|TEXT|BINARY|U8TEXT|WTEXT|U16TEXT]
SHARED=[YES|NO]
WCEM=[n|h|u|s|e|8|b]
ENCODING=[UTF8|8BITS]
The use of these parameters is described later in this section. If an
unrecognized keyword appears in a form string, it is silently ignored
and not considered invalid.
.. _Direct_IO:
Direct_IO
=========
Direct_IO can only be instantiated for definite types. This is a
restriction of the Ada language, which means that the records are fixed
length (the length being determined by ``type'Size``, rounded
up to the next storage unit boundary if necessary).
The records of a Direct_IO file are simply written to the file in index
sequence, with the first record starting at offset zero, and subsequent
records following. There is no control information of any kind. For
example, if 32-bit integers are being written, each record takes
4-bytes, so the record at index `K` starts at offset
(`K`-1)*4.
There is no limit on the size of Direct_IO files, they are expanded as
necessary to accommodate whatever records are written to the file.
.. _Sequential_IO:
Sequential_IO
=============
Sequential_IO may be instantiated with either a definite (constrained)
or indefinite (unconstrained) type.
For the definite type case, the elements written to the file are simply
the memory images of the data values with no control information of any
kind. The resulting file should be read using the same type, no validity
checking is performed on input.
For the indefinite type case, the elements written consist of two
parts. First is the size of the data item, written as the memory image
of a `Interfaces.C.size_t` value, followed by the memory image of
the data value. The resulting file can only be read using the same
(unconstrained) type. Normal assignment checks are performed on these
read operations, and if these checks fail, `Data_Error` is
raised. In particular, in the array case, the lengths must match, and in
the variant record case, if the variable for a particular read operation
is constrained, the discriminants must match.
Note that it is not possible to use Sequential_IO to write variable
length array items, and then read the data back into different length
arrays. For example, the following will raise `Data_Error`:
.. code-block:: ada
package IO is new Sequential_IO (String);
F : IO.File_Type;
S : String (1..4);
...
IO.Create (F)
IO.Write (F, "hello!")
IO.Reset (F, Mode=>In_File);
IO.Read (F, S);
Put_Line (S);
On some Ada implementations, this will print `hell`, but the program is
clearly incorrect, since there is only one element in the file, and that
element is the string `hello!`.
In Ada 95 and Ada 2005, this kind of behavior can be legitimately achieved
using Stream_IO, and this is the preferred mechanism. In particular, the
above program fragment rewritten to use Stream_IO will work correctly.
.. _Text_IO:
Text_IO
=======
Text_IO files consist of a stream of characters containing the following
special control characters:
::
LF (line feed, 16#0A#) Line Mark
FF (form feed, 16#0C#) Page Mark
A canonical Text_IO file is defined as one in which the following
conditions are met:
*
The character `LF` is used only as a line mark, i.e., to mark the end
of the line.
*
The character `FF` is used only as a page mark, i.e., to mark the
end of a page and consequently can appear only immediately following a
`LF` (line mark) character.
*
The file ends with either `LF` (line mark) or `LF`-`FF`
(line mark, page mark). In the former case, the page mark is implicitly
assumed to be present.
A file written using Text_IO will be in canonical form provided that no
explicit `LF` or `FF` characters are written using `Put`
or `Put_Line`. There will be no `FF` character at the end of
the file unless an explicit `New_Page` operation was performed
before closing the file.
A canonical Text_IO file that is a regular file (i.e., not a device or a
pipe) can be read using any of the routines in Text_IO. The
semantics in this case will be exactly as defined in the Ada Reference
Manual, and all the routines in Text_IO are fully implemented.
A text file that does not meet the requirements for a canonical Text_IO
file has one of the following:
*
The file contains `FF` characters not immediately following a
`LF` character.
*
The file contains `LF` or `FF` characters written by
`Put` or `Put_Line`, which are not logically considered to be
line marks or page marks.
*
The file ends in a character other than `LF` or `FF`,
i.e., there is no explicit line mark or page mark at the end of the file.
Text_IO can be used to read such non-standard text files but subprograms
to do with line or page numbers do not have defined meanings. In
particular, a `FF` character that does not follow a `LF`
character may or may not be treated as a page mark from the point of
view of page and line numbering. Every `LF` character is considered
to end a line, and there is an implied `LF` character at the end of
the file.
.. _Stream_Pointer_Positioning:
Stream Pointer Positioning
--------------------------
`Ada.Text_IO` has a definition of current position for a file that
is being read. No internal buffering occurs in Text_IO, and usually the
physical position in the stream used to implement the file corresponds
to this logical position defined by Text_IO. There are two exceptions:
*
After a call to `End_Of_Page` that returns `True`, the stream
is positioned past the `LF` (line mark) that precedes the page
mark. Text_IO maintains an internal flag so that subsequent read
operations properly handle the logical position which is unchanged by
the `End_Of_Page` call.
*
After a call to `End_Of_File` that returns `True`, if the
Text_IO file was positioned before the line mark at the end of file
before the call, then the logical position is unchanged, but the stream
is physically positioned right at the end of file (past the line mark,
and past a possible page mark following the line mark. Again Text_IO
maintains internal flags so that subsequent read operations properly
handle the logical position.
These discrepancies have no effect on the observable behavior of
Text_IO, but if a single Ada stream is shared between a C program and
Ada program, or shared (using ``shared=yes`` in the form string)
between two Ada files, then the difference may be observable in some
situations.
.. _Reading_and_Writing_Non-Regular_Files:
Reading and Writing Non-Regular Files
-------------------------------------
A non-regular file is a device (such as a keyboard), or a pipe. Text_IO
can be used for reading and writing. Writing is not affected and the
sequence of characters output is identical to the normal file case, but
for reading, the behavior of Text_IO is modified to avoid undesirable
look-ahead as follows:
An input file that is not a regular file is considered to have no page
marks. Any `Ascii.FF` characters (the character normally used for a
page mark) appearing in the file are considered to be data
characters. In particular:
*
`Get_Line` and `Skip_Line` do not test for a page mark
following a line mark. If a page mark appears, it will be treated as a
data character.
*
This avoids the need to wait for an extra character to be typed or
entered from the pipe to complete one of these operations.
*
`End_Of_Page` always returns `False`
*
`End_Of_File` will return `False` if there is a page mark at
the end of the file.
Output to non-regular files is the same as for regular files. Page marks
may be written to non-regular files using `New_Page`, but as noted
above they will not be treated as page marks on input if the output is
piped to another Ada program.
Another important discrepancy when reading non-regular files is that the end
of file indication is not 'sticky'. If an end of file is entered, e.g., by
pressing the :kbd:`EOT` key,
then end of file
is signaled once (i.e., the test `End_Of_File`
will yield `True`, or a read will
raise `End_Error`), but then reading can resume
to read data past that end of
file indication, until another end of file indication is entered.
.. _Get_Immediate:
Get_Immediate
-------------
.. index:: Get_Immediate
Get_Immediate returns the next character (including control characters)
from the input file. In particular, Get_Immediate will return LF or FF
characters used as line marks or page marks. Such operations leave the
file positioned past the control character, and it is thus not treated
as having its normal function. This means that page, line and column
counts after this kind of Get_Immediate call are set as though the mark
did not occur. In the case where a Get_Immediate leaves the file
positioned between the line mark and page mark (which is not normally
possible), it is undefined whether the FF character will be treated as a
page mark.
.. _Treating_Text_IO_Files_as_Streams:
Treating Text_IO Files as Streams
---------------------------------
.. index:: Stream files
The package `Text_IO.Streams` allows a Text_IO file to be treated
as a stream. Data written to a Text_IO file in this stream mode is
binary data. If this binary data contains bytes 16#0A# (`LF`) or
16#0C# (`FF`), the resulting file may have non-standard
format. Similarly if read operations are used to read from a Text_IO
file treated as a stream, then `LF` and `FF` characters may be
skipped and the effect is similar to that described above for
`Get_Immediate`.
.. _Text_IO_Extensions:
Text_IO Extensions
------------------
.. index:: Text_IO extensions
A package GNAT.IO_Aux in the GNAT library provides some useful extensions
to the standard `Text_IO` package:
* function File_Exists (Name : String) return Boolean;
Determines if a file of the given name exists.
* function Get_Line return String;
Reads a string from the standard input file. The value returned is exactly
the length of the line that was read.
* function Get_Line (File : Ada.Text_IO.File_Type) return String;
Similar, except that the parameter File specifies the file from which
the string is to be read.
.. _Text_IO_Facilities_for_Unbounded_Strings:
Text_IO Facilities for Unbounded Strings
----------------------------------------
.. index:: Text_IO for unbounded strings
.. index:: Unbounded_String, Text_IO operations
The package `Ada.Strings.Unbounded.Text_IO`
in library files `a-suteio.ads/adb` contains some GNAT-specific
subprograms useful for Text_IO operations on unbounded strings:
* function Get_Line (File : File_Type) return Unbounded_String;
Reads a line from the specified file
and returns the result as an unbounded string.
* procedure Put (File : File_Type; U : Unbounded_String);
Writes the value of the given unbounded string to the specified file
Similar to the effect of
`Put (To_String (U))` except that an extra copy is avoided.
* procedure Put_Line (File : File_Type; U : Unbounded_String);
Writes the value of the given unbounded string to the specified file,
followed by a `New_Line`.
Similar to the effect of `Put_Line (To_String (U))` except
that an extra copy is avoided.
In the above procedures, `File` is of type `Ada.Text_IO.File_Type`
and is optional. If the parameter is omitted, then the standard input or
output file is referenced as appropriate.
The package `Ada.Strings.Wide_Unbounded.Wide_Text_IO` in library
files :file:`a-swuwti.ads` and :file:`a-swuwti.adb` provides similar extended
`Wide_Text_IO` functionality for unbounded wide strings.
The package `Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO` in library
files :file:`a-szuzti.ads` and :file:`a-szuzti.adb` provides similar extended
`Wide_Wide_Text_IO` functionality for unbounded wide wide strings.
.. _Wide_Text_IO:
Wide_Text_IO
============
`Wide_Text_IO` is similar in most respects to Text_IO, except that
both input and output files may contain special sequences that represent
wide character values. The encoding scheme for a given file may be
specified using a FORM parameter:
::
WCEM=`x`
as part of the FORM string (WCEM = wide character encoding method),
where `x` is one of the following characters
========== ====================
Character Encoding
========== ====================
*h* Hex ESC encoding
*u* Upper half encoding
*s* Shift-JIS encoding
*e* EUC Encoding
*8* UTF-8 encoding
*b* Brackets encoding
========== ====================
The encoding methods match those that
can be used in a source
program, but there is no requirement that the encoding method used for
the source program be the same as the encoding method used for files,
and different files may use different encoding methods.
The default encoding method for the standard files, and for opened files
for which no WCEM parameter is given in the FORM string matches the
wide character encoding specified for the main program (the default
being brackets encoding if no coding method was specified with -gnatW).
*Hex Coding*
In this encoding, a wide character is represented by a five character
sequence:
::
ESC a b c d
..
where `a`, `b`, `c`, `d` are the four hexadecimal
characters (using upper case letters) of the wide character code. For
example, ESC A345 is used to represent the wide character with code
16#A345#. This scheme is compatible with use of the full
`Wide_Character` set.
*Upper Half Coding*
The wide character with encoding 16#abcd#, where the upper bit is on
(i.e., a is in the range 8-F) is represented as two bytes 16#ab# and
16#cd#. The second byte may never be a format control character, but is
not required to be in the upper half. This method can be also used for
shift-JIS or EUC where the internal coding matches the external coding.
*Shift JIS Coding*
A wide character is represented by a two character sequence 16#ab# and
16#cd#, with the restrictions described for upper half encoding as
described above. The internal character code is the corresponding JIS
character according to the standard algorithm for Shift-JIS
conversion. Only characters defined in the JIS code set table can be
used with this encoding method.
*EUC Coding*
A wide character is represented by a two character sequence 16#ab# and
16#cd#, with both characters being in the upper half. The internal
character code is the corresponding JIS character according to the EUC
encoding algorithm. Only characters defined in the JIS code set table
can be used with this encoding method.
*UTF-8 Coding*
A wide character is represented using
UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
10646-1/Am.2. Depending on the character value, the representation
is a one, two, or three byte sequence:
::
16#0000#-16#007f#: 2#0xxxxxxx#
16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx#
16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#
..
where the `xxx` bits correspond to the left-padded bits of the
16-bit character value. Note that all lower half ASCII characters
are represented as ASCII bytes and all upper half characters and
other wide characters are represented as sequences of upper-half
(The full UTF-8 scheme allows for encoding 31-bit characters as
6-byte sequences, but in this implementation, all UTF-8 sequences
of four or more bytes length will raise a Constraint_Error, as
will all invalid UTF-8 sequences.)
*Brackets Coding*
In this encoding, a wide character is represented by the following eight
character sequence:
::
[ " a b c d " ]
..
where `a`, `b`, `c`, `d` are the four hexadecimal
characters (using uppercase letters) of the wide character code. For
example, `["A345"]` is used to represent the wide character with code
`16#A345#`.
This scheme is compatible with use of the full Wide_Character set.
On input, brackets coding can also be used for upper half characters,
e.g., `["C1"]` for lower case a. However, on output, brackets notation
is only used for wide characters with a code greater than `16#FF#`.
Note that brackets coding is not normally used in the context of
Wide_Text_IO or Wide_Wide_Text_IO, since it is really just designed as
a portable way of encoding source files. In the context of Wide_Text_IO
or Wide_Wide_Text_IO, it can only be used if the file does not contain
any instance of the left bracket character other than to encode wide
character values using the brackets encoding method. In practice it is
expected that some standard wide character encoding method such
as UTF-8 will be used for text input output.
If brackets notation is used, then any occurrence of a left bracket
in the input file which is not the start of a valid wide character
sequence will cause Constraint_Error to be raised. It is possible to
encode a left bracket as ["5B"] and Wide_Text_IO and Wide_Wide_Text_IO
input will interpret this as a left bracket.
However, when a left bracket is output, it will be output as a left bracket
and not as ["5B"]. We make this decision because for normal use of
Wide_Text_IO for outputting messages, it is unpleasant to clobber left
brackets. For example, if we write:
.. code-block:: ada
Put_Line ("Start of output [first run]");
we really do not want to have the left bracket in this message clobbered so
that the output reads:
::
Start of output ["5B"]first run]
..
In practice brackets encoding is reasonably useful for normal Put_Line use
since we won't get confused between left brackets and wide character
sequences in the output. But for input, or when files are written out
and read back in, it really makes better sense to use one of the standard
encoding methods such as UTF-8.
For the coding schemes other than UTF-8, Hex, or Brackets encoding,
not all wide character
values can be represented. An attempt to output a character that cannot
be represented using the encoding scheme for the file causes
Constraint_Error to be raised. An invalid wide character sequence on
input also causes Constraint_Error to be raised.
.. _Stream_Pointer_Positioning_1:
Stream Pointer Positioning
--------------------------
`Ada.Wide_Text_IO` is similar to `Ada.Text_IO` in its handling
of stream pointer positioning (:ref:`Text_IO`). There is one additional
case:
If `Ada.Wide_Text_IO.Look_Ahead` reads a character outside the
normal lower ASCII set (i.e., a character in the range:
.. code-block:: ada
Wide_Character'Val (16#0080#) .. Wide_Character'Val (16#FFFF#)
then although the logical position of the file pointer is unchanged by
the `Look_Ahead` call, the stream is physically positioned past the
wide character sequence. Again this is to avoid the need for buffering
or backup, and all `Wide_Text_IO` routines check the internal
indication that this situation has occurred so that this is not visible
to a normal program using `Wide_Text_IO`. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
.. _Reading_and_Writing_Non-Regular_Files_1:
Reading and Writing Non-Regular Files
-------------------------------------
As in the case of Text_IO, when a non-regular file is read, it is
assumed that the file contains no page marks (any form characters are
treated as data characters), and `End_Of_Page` always returns
`False`. Similarly, the end of file indication is not sticky, so
it is possible to read beyond an end of file.
.. _Wide_Wide_Text_IO:
Wide_Wide_Text_IO
=================
`Wide_Wide_Text_IO` is similar in most respects to Text_IO, except that
both input and output files may contain special sequences that represent
wide wide character values. The encoding scheme for a given file may be
specified using a FORM parameter:
::
WCEM=`x`
as part of the FORM string (WCEM = wide character encoding method),
where `x` is one of the following characters
========== ====================
Character Encoding
========== ====================
*h* Hex ESC encoding
*u* Upper half encoding
*s* Shift-JIS encoding
*e* EUC Encoding
*8* UTF-8 encoding
*b* Brackets encoding
========== ====================
The encoding methods match those that
can be used in a source
program, but there is no requirement that the encoding method used for
the source program be the same as the encoding method used for files,
and different files may use different encoding methods.
The default encoding method for the standard files, and for opened files
for which no WCEM parameter is given in the FORM string matches the
wide character encoding specified for the main program (the default
being brackets encoding if no coding method was specified with -gnatW).
*UTF-8 Coding*
A wide character is represented using
UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
10646-1/Am.2. Depending on the character value, the representation
is a one, two, three, or four byte sequence:
::
16#000000#-16#00007f#: 2#0xxxxxxx#
16#000080#-16#0007ff#: 2#110xxxxx# 2#10xxxxxx#
16#000800#-16#00ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#
16#010000#-16#10ffff#: 2#11110xxx# 2#10xxxxxx# 2#10xxxxxx# 2#10xxxxxx#
..
where the `xxx` bits correspond to the left-padded bits of the
21-bit character value. Note that all lower half ASCII characters
are represented as ASCII bytes and all upper half characters and
other wide characters are represented as sequences of upper-half
characters.
*Brackets Coding*
In this encoding, a wide wide character is represented by the following eight
character sequence if is in wide character range
::
[ " a b c d " ]
..
and by the following ten character sequence if not
::
[ " a b c d e f " ]
..
where `a`, `b`, `c`, `d`, `e`, and `f`
are the four or six hexadecimal
characters (using uppercase letters) of the wide wide character code. For
example, `["01A345"]` is used to represent the wide wide character
with code `16#01A345#`.
This scheme is compatible with use of the full Wide_Wide_Character set.
On input, brackets coding can also be used for upper half characters,
e.g., `["C1"]` for lower case a. However, on output, brackets notation
is only used for wide characters with a code greater than `16#FF#`.
If is also possible to use the other Wide_Character encoding methods,
such as Shift-JIS, but the other schemes cannot support the full range
of wide wide characters.
An attempt to output a character that cannot
be represented using the encoding scheme for the file causes
Constraint_Error to be raised. An invalid wide character sequence on
input also causes Constraint_Error to be raised.
.. _Stream_Pointer_Positioning_2:
Stream Pointer Positioning
--------------------------
`Ada.Wide_Wide_Text_IO` is similar to `Ada.Text_IO` in its handling
of stream pointer positioning (:ref:`Text_IO`). There is one additional
case:
If `Ada.Wide_Wide_Text_IO.Look_Ahead` reads a character outside the
normal lower ASCII set (i.e., a character in the range:
.. code-block:: ada
Wide_Wide_Character'Val (16#0080#) .. Wide_Wide_Character'Val (16#10FFFF#)
then although the logical position of the file pointer is unchanged by
the `Look_Ahead` call, the stream is physically positioned past the
wide character sequence. Again this is to avoid the need for buffering
or backup, and all `Wide_Wide_Text_IO` routines check the internal
indication that this situation has occurred so that this is not visible
to a normal program using `Wide_Wide_Text_IO`. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
.. _Reading_and_Writing_Non-Regular_Files_2:
Reading and Writing Non-Regular Files
-------------------------------------
As in the case of Text_IO, when a non-regular file is read, it is
assumed that the file contains no page marks (any form characters are
treated as data characters), and `End_Of_Page` always returns
`False`. Similarly, the end of file indication is not sticky, so
it is possible to read beyond an end of file.
.. _Stream_IO:
Stream_IO
=========
A stream file is a sequence of bytes, where individual elements are
written to the file as described in the Ada Reference Manual. The type
`Stream_Element` is simply a byte. There are two ways to read or
write a stream file.
*
The operations `Read` and `Write` directly read or write a
sequence of stream elements with no control information.
*
The stream attributes applied to a stream file transfer data in the
manner described for stream attributes.
.. _Text_Translation:
Text Translation
================
``Text_Translation=xxx`` may be used as the Form parameter
passed to Text_IO.Create and Text_IO.Open. ``Text_Translation=xxx``
has no effect on Unix systems. Possible values are:
*
``Yes`` or ``Text`` is the default, which means to
translate LF to/from CR/LF on Windows systems.
``No`` disables this translation; i.e. it
uses binary mode. For output files, ``Text_Translation=No``
may be used to create Unix-style files on
Windows.
*
``wtext`` translation enabled in Unicode mode.
(corresponds to _O_WTEXT).
*
``u8text`` translation enabled in Unicode UTF-8 mode.
(corresponds to O_U8TEXT).
*
``u16text`` translation enabled in Unicode UTF-16
mode. (corresponds to_O_U16TEXT).
.. _Shared_Files:
Shared Files
============
Section A.14 of the Ada Reference Manual allows implementations to
provide a wide variety of behavior if an attempt is made to access the
same external file with two or more internal files.
To provide a full range of functionality, while at the same time
minimizing the problems of portability caused by this implementation
dependence, GNAT handles file sharing as follows:
*
In the absence of a ``shared=xxx`` form parameter, an attempt
to open two or more files with the same full name is considered an error
and is not supported. The exception `Use_Error` will be
raised. Note that a file that is not explicitly closed by the program
remains open until the program terminates.
*
If the form parameter ``shared=no`` appears in the form string, the
file can be opened or created with its own separate stream identifier,
regardless of whether other files sharing the same external file are
opened. The exact effect depends on how the C stream routines handle
multiple accesses to the same external files using separate streams.
*
If the form parameter ``shared=yes`` appears in the form string for
each of two or more files opened using the same full name, the same
stream is shared between these files, and the semantics are as described
in Ada Reference Manual, Section A.14.
When a program that opens multiple files with the same name is ported
from another Ada compiler to GNAT, the effect will be that
`Use_Error` is raised.
The documentation of the original compiler and the documentation of the
program should then be examined to determine if file sharing was
expected, and ``shared=xxx`` parameters added to `Open`
and `Create` calls as required.
When a program is ported from GNAT to some other Ada compiler, no
special attention is required unless the ``shared=xxx`` form
parameter is used in the program. In this case, you must examine the
documentation of the new compiler to see if it supports the required
file sharing semantics, and form strings modified appropriately. Of
course it may be the case that the program cannot be ported if the
target compiler does not support the required functionality. The best
approach in writing portable code is to avoid file sharing (and hence
the use of the ``shared=xxx`` parameter in the form string)
completely.
One common use of file sharing in Ada 83 is the use of instantiations of
Sequential_IO on the same file with different types, to achieve
heterogeneous input-output. Although this approach will work in GNAT if
``shared=yes`` is specified, it is preferable in Ada to use Stream_IO
for this purpose (using the stream attributes)
.. _Filenames_encoding:
Filenames encoding
==================
An encoding form parameter can be used to specify the filename
encoding ``encoding=xxx``.
*
If the form parameter ``encoding=utf8`` appears in the form string, the
filename must be encoded in UTF-8.
*
If the form parameter ``encoding=8bits`` appears in the form
string, the filename must be a standard 8bits string.
In the absence of a ``encoding=xxx`` form parameter, the
encoding is controlled by the ``GNAT_CODE_PAGE`` environment
variable. And if not set ``utf8`` is assumed.
*CP_ACP*
The current system Windows ANSI code page.
*CP_UTF8*
UTF-8 encoding
This encoding form parameter is only supported on the Windows
platform. On the other Operating Systems the run-time is supporting
UTF-8 natively.
.. _File_content_encoding:
File content encoding
=====================
For text files it is possible to specify the encoding to use. This is
controlled by the by the ``GNAT_CCS_ENCODING`` environment
variable. And if not set ``TEXT`` is assumed.
The possible values are those supported on Windows:
*TEXT*
Translated text mode
*WTEXT*
Translated unicode encoding
*U16TEXT*
Unicode 16-bit encoding
*U8TEXT*
Unicode 8-bit encoding
This encoding is only supported on the Windows platform.
.. _Open_Modes:
Open Modes
==========
`Open` and `Create` calls result in a call to `fopen`
using the mode shown in the following table:
+----------------------------+---------------+------------------+
| `Open` and `Create` Call Modes |
+----------------------------+---------------+------------------+
| | **OPEN** | **CREATE** |
+============================+===============+==================+
| Append_File | "r+" | "w+" |
+----------------------------+---------------+------------------+
| In_File | "r" | "w+" |
+----------------------------+---------------+------------------+
| Out_File (Direct_IO) | "r+" | "w" |
+----------------------------+---------------+------------------+
| Out_File (all other cases) | "w" | "w" |
+----------------------------+---------------+------------------+
| Inout_File | "r+" | "w+" |
+----------------------------+---------------+------------------+
If text file translation is required, then either ``b`` or ``t``
is added to the mode, depending on the setting of Text. Text file
translation refers to the mapping of CR/LF sequences in an external file
to LF characters internally. This mapping only occurs in DOS and
DOS-like systems, and is not relevant to other systems.
A special case occurs with Stream_IO. As shown in the above table, the
file is initially opened in ``r`` or ``w`` mode for the
`In_File` and `Out_File` cases. If a `Set_Mode` operation
subsequently requires switching from reading to writing or vice-versa,
then the file is reopened in ``r+`` mode to permit the required operation.
.. _Operations_on_C_Streams:
Operations on C Streams
=======================
The package `Interfaces.C_Streams` provides an Ada program with direct
access to the C library functions for operations on C streams:
.. code-block:: ada
package Interfaces.C_Streams is
-- Note: the reason we do not use the types that are in
-- Interfaces.C is that we want to avoid dragging in the
-- code in this unit if possible.
subtype chars is System.Address;
-- Pointer to null-terminated array of characters
subtype FILEs is System.Address;
-- Corresponds to the C type FILE*
subtype voids is System.Address;
-- Corresponds to the C type void*
subtype int is Integer;
subtype long is Long_Integer;
-- Note: the above types are subtypes deliberately, and it
-- is part of this spec that the above correspondences are
-- guaranteed. This means that it is legitimate to, for
-- example, use Integer instead of int. We provide these
-- synonyms for clarity, but in some cases it may be
-- convenient to use the underlying types (for example to
-- avoid an unnecessary dependency of a spec on the spec
-- of this unit).
type size_t is mod 2 ** Standard'Address_Size;
NULL_Stream : constant FILEs;
-- Value returned (NULL in C) to indicate an
-- fdopen/fopen/tmpfile error
----------------------------------
-- Constants Defined in stdio.h --
----------------------------------
EOF : constant int;
-- Used by a number of routines to indicate error or
-- end of file
IOFBF : constant int;
IOLBF : constant int;
IONBF : constant int;
-- Used to indicate buffering mode for setvbuf call
SEEK_CUR : constant int;
SEEK_END : constant int;
SEEK_SET : constant int;
-- Used to indicate origin for fseek call
function stdin return FILEs;
function stdout return FILEs;
function stderr return FILEs;
-- Streams associated with standard files
--------------------------
-- Standard C functions --
--------------------------
-- The functions selected below are ones that are
-- available in UNIX (but not necessarily in ANSI C).
-- These are very thin interfaces
-- which copy exactly the C headers. For more
-- documentation on these functions, see the Microsoft C
-- "Run-Time Library Reference" (Microsoft Press, 1990,
-- ISBN 1-55615-225-6), which includes useful information
-- on system compatibility.
procedure clearerr (stream : FILEs);
function fclose (stream : FILEs) return int;
function fdopen (handle : int; mode : chars) return FILEs;
function feof (stream : FILEs) return int;
function ferror (stream : FILEs) return int;
function fflush (stream : FILEs) return int;
function fgetc (stream : FILEs) return int;
function fgets (strng : chars; n : int; stream : FILEs)
return chars;
function fileno (stream : FILEs) return int;
function fopen (filename : chars; Mode : chars)
return FILEs;
-- Note: to maintain target independence, use
-- text_translation_required, a boolean variable defined in
-- a-sysdep.c to deal with the target dependent text
-- translation requirement. If this variable is set,
-- then b/t should be appended to the standard mode
-- argument to set the text translation mode off or on
-- as required.
function fputc (C : int; stream : FILEs) return int;
function fputs (Strng : chars; Stream : FILEs) return int;
function fread
(buffer : voids;
size : size_t;
count : size_t;
stream : FILEs)
return size_t;
function freopen
(filename : chars;
mode : chars;
stream : FILEs)
return FILEs;
function fseek
(stream : FILEs;
offset : long;
origin : int)
return int;
function ftell (stream : FILEs) return long;
function fwrite
(buffer : voids;
size : size_t;
count : size_t;
stream : FILEs)
return size_t;
function isatty (handle : int) return int;
procedure mktemp (template : chars);
-- The return value (which is just a pointer to template)
-- is discarded
procedure rewind (stream : FILEs);
function rmtmp return int;
function setvbuf
(stream : FILEs;
buffer : chars;
mode : int;
size : size_t)
return int;
function tmpfile return FILEs;
function ungetc (c : int; stream : FILEs) return int;
function unlink (filename : chars) return int;
---------------------
-- Extra functions --
---------------------
-- These functions supply slightly thicker bindings than
-- those above. They are derived from functions in the
-- C Run-Time Library, but may do a bit more work than
-- just directly calling one of the Library functions.
function is_regular_file (handle : int) return int;
-- Tests if given handle is for a regular file (result 1)
-- or for a non-regular file (pipe or device, result 0).
---------------------------------
-- Control of Text/Binary Mode --
---------------------------------
-- If text_translation_required is true, then the following
-- functions may be used to dynamically switch a file from
-- binary to text mode or vice versa. These functions have
-- no effect if text_translation_required is false (i.e., in
-- normal UNIX mode). Use fileno to get a stream handle.
procedure set_binary_mode (handle : int);
procedure set_text_mode (handle : int);
----------------------------
-- Full Path Name support --
----------------------------
procedure full_name (nam : chars; buffer : chars);
-- Given a NUL terminated string representing a file
-- name, returns in buffer a NUL terminated string
-- representing the full path name for the file name.
-- On systems where it is relevant the drive is also
-- part of the full path name. It is the responsibility
-- of the caller to pass an actual parameter for buffer
-- that is big enough for any full path name. Use
-- max_path_len given below as the size of buffer.
max_path_len : integer;
-- Maximum length of an allowable full path name on the
-- system, including a terminating NUL character.
end Interfaces.C_Streams;
.. _Interfacing_to_C_Streams:
Interfacing to C Streams
========================
The packages in this section permit interfacing Ada files to C Stream
operations.
.. code-block:: ada
with Interfaces.C_Streams;
package Ada.Sequential_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Sequential_IO.C_Streams;
with Interfaces.C_Streams;
package Ada.Direct_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Direct_IO.C_Streams;
with Interfaces.C_Streams;
package Ada.Text_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Text_IO.C_Streams;
with Interfaces.C_Streams;
package Ada.Wide_Text_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Wide_Text_IO.C_Streams;
with Interfaces.C_Streams;
package Ada.Wide_Wide_Text_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Wide_Wide_Text_IO.C_Streams;
with Interfaces.C_Streams;
package Ada.Stream_IO.C_Streams is
function C_Stream (F : File_Type)
return Interfaces.C_Streams.FILEs;
procedure Open
(File : in out File_Type;
Mode : in File_Mode;
C_Stream : in Interfaces.C_Streams.FILEs;
Form : in String := "");
end Ada.Stream_IO.C_Streams;
In each of these six packages, the `C_Stream` function obtains the
`FILE` pointer from a currently opened Ada file. It is then
possible to use the `Interfaces.C_Streams` package to operate on
this stream, or the stream can be passed to a C program which can
operate on it directly. Of course the program is responsible for
ensuring that only appropriate sequences of operations are executed.
One particular use of relevance to an Ada program is that the
`setvbuf` function can be used to control the buffering of the
stream used by an Ada file. In the absence of such a call the standard
default buffering is used.
The `Open` procedures in these packages open a file giving an
existing C Stream instead of a file name. Typically this stream is
imported from a C program, allowing an Ada file to operate on an
existing C file.
GNAT User's Guide for Native Platforms
======================================
*GNAT, The GNU Ada Development Environment*
.. only:: PRO
*GNAT Pro Edition*
| Version |version|
| Date: |today|
.. only:: GPL
*GNAT GPL Edition*
| Version |version|
| Date: |today|
.. only:: FSF
.. raw:: texinfo
@include gcc-common.texi
GCC version @value{version-GCC}@*
AdaCore
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover Texts being
"GNAT User's Guide for Native Platforms",
and with no Back-Cover Texts. A copy of the license is
included in the section entitled :ref:`gnu_fdl`.
.. toctree::
:maxdepth: 3
:numbered:
gnat_ugn/about_this_guide
gnat_ugn/getting_started_with_gnat
gnat_ugn/the_gnat_compilation_model
gnat_ugn/building_executable_programs_with_gnat
gnat_ugn/gnat_project_manager
gnat_ugn/tools_supporting_project_files
gnat_ugn/gnat_utility_programs
gnat_ugn/gnat_and_program_execution
.. raw:: latex
\appendix
.. toctree::
:maxdepth: 3
A. Platform-Specific Information <gnat_ugn/platform_specific_information>
B. Example of Binder Output <gnat_ugn/example_of_binder_output>
C. Elaboration Order Handling in GNAT <gnat_ugn/elaboration_order_handling_in_gnat>
D. Inline Assembler <gnat_ugn/inline_assembler>
E. GNU Free Documentation License <share/gnu_free_documentation_license>
.. _About_This_Guide:
About This Guide
~~~~~~~~~~~~~~~~
.. only:: PRO
For ease of exposition, 'GNAT Pro' will be referred to simply as
'GNAT' in the remainder of this document.
This guide describes the use of GNAT,
a compiler and software development
toolset for the full Ada programming language.
It documents the features of the compiler and tools, and explains
how to use them to build Ada applications.
GNAT implements Ada 95, Ada 2005 and Ada 2012, and it may also be
invoked in Ada 83 compatibility mode.
By default, GNAT assumes Ada 2012, but you can override with a
compiler switch (:ref:`Compiling_Different_Versions_of_Ada`)
to explicitly specify the language version.
Throughout this manual, references to 'Ada' without a year suffix
apply to all Ada 95/2005/2012 versions of the language.
What This Guide Contains
========================
This guide contains the following chapters:
* :ref:`Getting_Started_with_GNAT` describes how to get started compiling
and running Ada programs with the GNAT Ada programming environment.
* :ref:`The_GNAT_Compilation_Model` describes the compilation model used
by GNAT.
* :ref:`Building_Executable_Programs_With_GNAT` describes how to use the
main GNAT tools to build executable programs, and it also gives examples of
using the GNU make utility with GNAT.
* :ref:`GNAT_Project_Manager` describes how to use project files
to organize large projects.
* :ref:`Tools_Supporting_Project_Files` described how to use the project
facility in conjunction with various GNAT tools.
* :ref:`GNAT_Utility_Programs` explains the various utility programs that
are included in the GNAT environment
* :ref:`GNAT_and_Program_Execution` covers a number of topics related to
running, debugging, and tuning the performace of programs developed
with GNAT
Appendices cover several additional topics:
* :ref:`Platform_Specific_Information` describes the different run-time
library implementations and also presents information on how to use
GNAT on several specific platforms
* :ref:`Example_of_Binder_Output_File` shows the source code for the binder
output file for a sample program.
* :ref:`Elaboration_Order_Handling_in_GNAT` describes how GNAT helps
you deal with elaboration order issues.
* :ref:`Inline_Assembler` shows how to use the inline assembly facility
in an Ada program.
What You Should Know before Reading This Guide
==============================================
.. index:: Ada 95 Language Reference Manual
.. index:: Ada 2005 Language Reference Manual
This guide assumes a basic familiarity with the Ada 95 language, as
described in the International Standard ANSI/ISO/IEC-8652:1995, January
1995.
It does not require knowledge of the features introduced by Ada 2005
or Ada 2012.
Reference manuals for Ada 95, Ada 2005, and Ada 2012 are included in
the GNAT documentation package.
Related Information
===================
For further information about Ada and related tools, please refer to the
following documents:
* :title:`Ada 95 Reference Manual`, :title:`Ada 2005 Reference Manual`, and
:title:`Ada 2012 Reference Manual`, which contain reference
material for the several revisions of the Ada language standard.
* :title:`GNAT Reference_Manual`, which contains all reference material for the GNAT
implementation of Ada.
* :title:`Using the GNAT Programming Studio`, which describes the GPS
Integrated Development Environment.
* :title:`GNAT Programming Studio Tutorial`, which introduces the
main GPS features through examples.
* :title:`Debugging with GDB`,
for all details on the use of the GNU source-level debugger.
* :title:`GNU Emacs Manual`,
for full information on the extensible editor and programming
environment Emacs.
A Note to Readers of Previous Versions of the Manual
====================================================
In early 2015 the GNAT manuals were transitioned to the
reStructuredText (rst) / Sphinx documentation generator technology.
During that process the :title:`GNAT User's Guide` was reorganized
so that related topics would be described together in the same chapter
or appendix. Here's a summary of the major changes realized in
the new document structure.
* :ref:`The_GNAT_Compilation_Model` has been extended so that it now covers
the following material:
- The `gnatname`, `gnatkr`, and `gnatchop` tools
- :ref:`Configuration_Pragmas`
- :ref:`GNAT_and_Libraries`
- :ref:`Conditional_Compilation` including :ref:`Preprocessing_with_gnatprep`
and :ref:`Integrated_Preprocessing`
- :ref:`Generating_Ada_Bindings_for_C_and_C++_headers`
- :ref:`Using_GNAT_Files_with_External_Tools`
* :ref:`Building_Executable_Programs_With_GNAT` is a new chapter consolidating
the following content:
- :ref:`The_GNAT_Make_Program_gnatmake`
- :ref:`Compiling_with_GCC`
- :ref:`Binding_with_gnatbind`
- :ref:`Linking_with_gnatlink`
- :ref:`Using_the_GNU_make_Utility`
* :ref:`GNAT_Utility_Programs` is a new chapter consolidating the information about several
GNAT tools:
.. only:: PRO or GPL
- :ref:`The_File_Cleanup_Utility_gnatclean`
- :ref:`The_GNAT_Library_Browser_gnatls`
- :ref:`The_Cross-Referencing_Tools_gnatxref_and_gnatfind`
- :ref:`The_Ada_to_HTML_Converter_gnathtml`
- :ref:`The_Ada-to-XML_Converter_gnat2xml`
- :ref:`The_Program_Property_Verifier_gnatcheck`
- :ref:`The_GNAT_Metrics_Tool_gnatmetric`
- :ref:`The_GNAT_Pretty-Printer_gnatpp`
- :ref:`The_Body_Stub_Generator_gnatstub`
- :ref:`The_Unit_Test_Generator_gnattest`
.. only:: FSF
- :ref:`The_File_Cleanup_Utility_gnatclean`
- :ref:`The_GNAT_Library_Browser_gnatls`
- :ref:`The_Cross-Referencing_Tools_gnatxref_and_gnatfind`
- :ref:`The_Ada_to_HTML_Converter_gnathtml`
* :ref:`GNAT_and_Program_Execution` is a new chapter consolidating the following:
- :ref:`Running_and_Debugging_Ada_Programs`
- :ref:`Code_Coverage_and_Profiling`
- :ref:`Improving_Performance`
- :ref:`Overflow Check Handling in GNAT <Overflow_Check_Handling_in_GNAT>`
- :ref:`Performing Dimensionality Analysis in GNAT <Performing_Dimensionality_Analysis_in_GNAT>`
- :ref:`Stack_Related_Facilities`
- :ref:`Memory_Management_Issues`
* :ref:`Platform_Specific_Information` is a new appendix consolidating the following:
- :ref:`Run_Time_Libraries`
- :ref:`Microsoft_Windows_Topics`
- :ref:`Mac_OS_Topics`
* The `Compatibility and Porting Guide` appendix has been moved to the
:title:`GNAT Reference Manual`. It now includes a section
`Writing Portable Fixed-Point Declarations` which was previously
a separate chapter in the :title:`GNAT User's Guide`.
Conventions
===========
.. index:: Conventions, typographical
.. index:: Typographical conventions
Following are examples of the typographical and graphic conventions used
in this guide:
* `Functions`, `utility program names`, `standard names`,
and `classes`.
* `Option flags`
* :file:`File names`
* `Variables`
* *Emphasis*
* [optional information or parameters]
* Examples are described by text
::
and then shown this way.
* Commands that are entered by the user are shown as preceded by a prompt string
comprising the ``$`` character followed by a space.
* Full file names are shown with the '/' character
as the directory separator; e.g., :file:`parent-dir/subdir/myfile.adb`.
If you are using GNAT on a Windows platform, please note that
the '\\' character should be used instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing
.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
.. _Elaboration_Order_Handling_in_GNAT:
**********************************
Elaboration Order Handling in GNAT
**********************************
.. index:: Order of elaboration
.. index:: Elaboration control
This appendix describes the handling of elaboration code in Ada and
in GNAT, and discusses how the order of elaboration of program units can
be controlled in GNAT, either automatically or with explicit programming
features.
.. _Elaboration_Code:
Elaboration Code
================
Ada provides rather general mechanisms for executing code at elaboration
time, that is to say before the main program starts executing. Such code arises
in three contexts:
* *Initializers for variables*
Variables declared at the library level, in package specs or bodies, can
require initialization that is performed at elaboration time, as in:
.. code-block:: ada
Sqrt_Half : Float := Sqrt (0.5);
* *Package initialization code*
Code in a `BEGIN-END` section at the outer level of a package body is
executed as part of the package body elaboration code.
* *Library level task allocators*
Tasks that are declared using task allocators at the library level
start executing immediately and hence can execute at elaboration time.
Subprogram calls are possible in any of these contexts, which means that
any arbitrary part of the program may be executed as part of the elaboration
code. It is even possible to write a program which does all its work at
elaboration time, with a null main program, although stylistically this
would usually be considered an inappropriate way to structure
a program.
An important concern arises in the context of elaboration code:
we have to be sure that it is executed in an appropriate order. What we
have is a series of elaboration code sections, potentially one section
for each unit in the program. It is important that these execute
in the correct order. Correctness here means that, taking the above
example of the declaration of `Sqrt_Half`,
if some other piece of
elaboration code references `Sqrt_Half`,
then it must run after the
section of elaboration code that contains the declaration of
`Sqrt_Half`.
There would never be any order of elaboration problem if we made a rule
that whenever you |with| a unit, you must elaborate both the spec and body
of that unit before elaborating the unit doing the |withing|:
.. code-block:: ada
with Unit_1;
package Unit_2 is ...
would require that both the body and spec of `Unit_1` be elaborated
before the spec of `Unit_2`. However, a rule like that would be far too
restrictive. In particular, it would make it impossible to have routines
in separate packages that were mutually recursive.
You might think that a clever enough compiler could look at the actual
elaboration code and determine an appropriate correct order of elaboration,
but in the general case, this is not possible. Consider the following
example.
In the body of `Unit_1`, we have a procedure `Func_1`
that references
the variable `Sqrt_1`, which is declared in the elaboration code
of the body of `Unit_1`:
.. code-block:: ada
Sqrt_1 : Float := Sqrt (0.1);
The elaboration code of the body of `Unit_1` also contains:
.. code-block:: ada
if expression_1 = 1 then
Q := Unit_2.Func_2;
end if;
`Unit_2` is exactly parallel,
it has a procedure `Func_2` that references
the variable `Sqrt_2`, which is declared in the elaboration code of
the body `Unit_2`:
.. code-block:: ada
Sqrt_2 : Float := Sqrt (0.1);
The elaboration code of the body of `Unit_2` also contains:
.. code-block:: ada
if expression_2 = 2 then
Q := Unit_1.Func_1;
end if;
Now the question is, which of the following orders of elaboration is
acceptable:
::
Spec of Unit_1
Spec of Unit_2
Body of Unit_1
Body of Unit_2
or
::
Spec of Unit_2
Spec of Unit_1
Body of Unit_2
Body of Unit_1
If you carefully analyze the flow here, you will see that you cannot tell
at compile time the answer to this question.
If `expression_1` is not equal to 1,
and `expression_2` is not equal to 2,
then either order is acceptable, because neither of the function calls is
executed. If both tests evaluate to true, then neither order is acceptable
and in fact there is no correct order.
If one of the two expressions is true, and the other is false, then one
of the above orders is correct, and the other is incorrect. For example,
if `expression_1` /= 1 and `expression_2` = 2,
then the call to `Func_1`
will occur, but not the call to `Func_2.`
This means that it is essential
to elaborate the body of `Unit_1` before
the body of `Unit_2`, so the first
order of elaboration is correct and the second is wrong.
By making `expression_1` and `expression_2`
depend on input data, or perhaps
the time of day, we can make it impossible for the compiler or binder
to figure out which of these expressions will be true, and hence it
is impossible to guarantee a safe order of elaboration at run time.
.. _Checking_the_Elaboration_Order:
Checking the Elaboration Order
==============================
In some languages that involve the same kind of elaboration problems,
e.g., Java and C++, the programmer needs to take these
ordering problems into account, and it is common to
write a program in which an incorrect elaboration order gives
surprising results, because it references variables before they
are initialized.
Ada is designed to be a safe language, and a programmer-beware approach is
clearly not sufficient. Consequently, the language provides three lines
of defense:
* *Standard rules*
Some standard rules restrict the possible choice of elaboration
order. In particular, if you |with| a unit, then its spec is always
elaborated before the unit doing the |with|. Similarly, a parent
spec is always elaborated before the child spec, and finally
a spec is always elaborated before its corresponding body.
.. index:: Elaboration checks
.. index:: Checks, elaboration
* *Dynamic elaboration checks*
Dynamic checks are made at run time, so that if some entity is accessed
before it is elaborated (typically by means of a subprogram call)
then the exception (`Program_Error`) is raised.
* *Elaboration control*
Facilities are provided for the programmer to specify the desired order
of elaboration.
Let's look at these facilities in more detail. First, the rules for
dynamic checking. One possible rule would be simply to say that the
exception is raised if you access a variable which has not yet been
elaborated. The trouble with this approach is that it could require
expensive checks on every variable reference. Instead Ada has two
rules which are a little more restrictive, but easier to check, and
easier to state:
* *Restrictions on calls*
A subprogram can only be called at elaboration time if its body
has been elaborated. The rules for elaboration given above guarantee
that the spec of the subprogram has been elaborated before the
call, but not the body. If this rule is violated, then the
exception `Program_Error` is raised.
* *Restrictions on instantiations*
A generic unit can only be instantiated if the body of the generic
unit has been elaborated. Again, the rules for elaboration given above
guarantee that the spec of the generic unit has been elaborated
before the instantiation, but not the body. If this rule is
violated, then the exception `Program_Error` is raised.
The idea is that if the body has been elaborated, then any variables
it references must have been elaborated; by checking for the body being
elaborated we guarantee that none of its references causes any
trouble. As we noted above, this is a little too restrictive, because a
subprogram that has no non-local references in its body may in fact be safe
to call. However, it really would be unsafe to rely on this, because
it would mean that the caller was aware of details of the implementation
in the body. This goes against the basic tenets of Ada.
A plausible implementation can be described as follows.
A Boolean variable is associated with each subprogram
and each generic unit. This variable is initialized to False, and is set to
True at the point body is elaborated. Every call or instantiation checks the
variable, and raises `Program_Error` if the variable is False.
Note that one might think that it would be good enough to have one Boolean
variable for each package, but that would not deal with cases of trying
to call a body in the same package as the call
that has not been elaborated yet.
Of course a compiler may be able to do enough analysis to optimize away
some of the Boolean variables as unnecessary, and `GNAT` indeed
does such optimizations, but still the easiest conceptual model is to
think of there being one variable per subprogram.
.. _Controlling_the_Elaboration_Order:
Controlling the Elaboration Order
=================================
In the previous section we discussed the rules in Ada which ensure
that `Program_Error` is raised if an incorrect elaboration order is
chosen. This prevents erroneous executions, but we need mechanisms to
specify a correct execution and avoid the exception altogether.
To achieve this, Ada provides a number of features for controlling
the order of elaboration. We discuss these features in this section.
First, there are several ways of indicating to the compiler that a given
unit has no elaboration problems:
* *packages that do not require a body*
A library package that does not require a body does not permit
a body (this rule was introduced in Ada 95).
Thus if we have a such a package, as in:
.. code-block:: ada
package Definitions is
generic
type m is new integer;
package Subp is
type a is array (1 .. 10) of m;
type b is array (1 .. 20) of m;
end Subp;
end Definitions;
A package that |withs| `Definitions` may safely instantiate
`Definitions.Subp` because the compiler can determine that there
definitely is no package body to worry about in this case
.. index:: pragma Pure
* *pragma Pure*
This pragma places sufficient restrictions on a unit to guarantee that
no call to any subprogram in the unit can result in an
elaboration problem. This means that the compiler does not need
to worry about the point of elaboration of such units, and in
particular, does not need to check any calls to any subprograms
in this unit.
.. index:: pragma Preelaborate
* *pragma Preelaborate*
This pragma places slightly less stringent restrictions on a unit than
does pragma Pure,
but these restrictions are still sufficient to ensure that there
are no elaboration problems with any calls to the unit.
.. index:: pragma Elaborate_Body
* *pragma Elaborate_Body*
This pragma requires that the body of a unit be elaborated immediately
after its spec. Suppose a unit `A` has such a pragma,
and unit `B` does
a |with| of unit `A`. Recall that the standard rules require
the spec of unit `A`
to be elaborated before the |withing| unit; given the pragma in
`A`, we also know that the body of `A`
will be elaborated before `B`, so
that calls to `A` are safe and do not need a check.
Note that, unlike pragma `Pure` and pragma `Preelaborate`,
the use of `Elaborate_Body` does not guarantee that the program is
free of elaboration problems, because it may not be possible
to satisfy the requested elaboration order.
Let's go back to the example with `Unit_1` and `Unit_2`.
If a programmer marks `Unit_1` as `Elaborate_Body`,
and not `Unit_2,` then the order of
elaboration will be::
Spec of Unit_2
Spec of Unit_1
Body of Unit_1
Body of Unit_2
Now that means that the call to `Func_1` in `Unit_2`
need not be checked,
it must be safe. But the call to `Func_2` in
`Unit_1` may still fail if
`Expression_1` is equal to 1,
and the programmer must still take
responsibility for this not being the case.
If all units carry a pragma `Elaborate_Body`, then all problems are
eliminated, except for calls entirely within a body, which are
in any case fully under programmer control. However, using the pragma
everywhere is not always possible.
In particular, for our `Unit_1`/`Unit_2` example, if
we marked both of them as having pragma `Elaborate_Body`, then
clearly there would be no possible elaboration order.
The above pragmas allow a server to guarantee safe use by clients, and
clearly this is the preferable approach. Consequently a good rule
is to mark units as `Pure` or `Preelaborate` if possible,
and if this is not possible,
mark them as `Elaborate_Body` if possible.
As we have seen, there are situations where neither of these
three pragmas can be used.
So we also provide methods for clients to control the
order of elaboration of the servers on which they depend:
.. index:: pragma Elaborate
* *pragma Elaborate (unit)*
This pragma is placed in the context clause, after a |with| clause,
and it requires that the body of the named unit be elaborated before
the unit in which the pragma occurs. The idea is to use this pragma
if the current unit calls at elaboration time, directly or indirectly,
some subprogram in the named unit.
.. index:: pragma Elaborate_All
* *pragma Elaborate_All (unit)*
This is a stronger version of the Elaborate pragma. Consider the
following example::
Unit A |withs| unit B and calls B.Func in elab code
Unit B |withs| unit C, and B.Func calls C.Func
Now if we put a pragma `Elaborate (B)`
in unit `A`, this ensures that the
body of `B` is elaborated before the call, but not the
body of `C`, so
the call to `C.Func` could still cause `Program_Error` to
be raised.
The effect of a pragma `Elaborate_All` is stronger, it requires
not only that the body of the named unit be elaborated before the
unit doing the |with|, but also the bodies of all units that the
named unit uses, following |with| links transitively. For example,
if we put a pragma `Elaborate_All (B)` in unit `A`,
then it requires not only that the body of `B` be elaborated before `A`,
but also the body of `C`, because `B` |withs| `C`.
We are now in a position to give a usage rule in Ada for avoiding
elaboration problems, at least if dynamic dispatching and access to
subprogram values are not used. We will handle these cases separately
later.
The rule is simple:
*If a unit has elaboration code that can directly or
indirectly make a call to a subprogram in a |withed| unit, or instantiate
a generic package in a |withed| unit,
then if the |withed| unit does not have
pragma `Pure` or `Preelaborate`, then the client should have
a pragma `Elaborate_All`for the |withed| unit.**
By following this rule a client is
assured that calls can be made without risk of an exception.
For generic subprogram instantiations, the rule can be relaxed to
require only a pragma `Elaborate` since elaborating the body
of a subprogram cannot cause any transitive elaboration (we are
not calling the subprogram in this case, just elaborating its
declaration).
If this rule is not followed, then a program may be in one of four
states:
* *No order exists*
No order of elaboration exists which follows the rules, taking into
account any `Elaborate`, `Elaborate_All`,
or `Elaborate_Body` pragmas. In
this case, an Ada compiler must diagnose the situation at bind
time, and refuse to build an executable program.
* *One or more orders exist, all incorrect*
One or more acceptable elaboration orders exist, and all of them
generate an elaboration order problem. In this case, the binder
can build an executable program, but `Program_Error` will be raised
when the program is run.
* *Several orders exist, some right, some incorrect*
One or more acceptable elaboration orders exists, and some of them
work, and some do not. The programmer has not controlled
the order of elaboration, so the binder may or may not pick one of
the correct orders, and the program may or may not raise an
exception when it is run. This is the worst case, because it means
that the program may fail when moved to another compiler, or even
another version of the same compiler.
* *One or more orders exists, all correct*
One ore more acceptable elaboration orders exist, and all of them
work. In this case the program runs successfully. This state of
affairs can be guaranteed by following the rule we gave above, but
may be true even if the rule is not followed.
Note that one additional advantage of following our rules on the use
of `Elaborate` and `Elaborate_All`
is that the program continues to stay in the ideal (all orders OK) state
even if maintenance
changes some bodies of some units. Conversely, if a program that does
not follow this rule happens to be safe at some point, this state of affairs
may deteriorate silently as a result of maintenance changes.
You may have noticed that the above discussion did not mention
the use of `Elaborate_Body`. This was a deliberate omission. If you
|with| an `Elaborate_Body` unit, it still may be the case that
code in the body makes calls to some other unit, so it is still necessary
to use `Elaborate_All` on such units.
.. _Controlling_Elaboration_in_GNAT_-_Internal_Calls:
Controlling Elaboration in GNAT - Internal Calls
================================================
In the case of internal calls, i.e., calls within a single package, the
programmer has full control over the order of elaboration, and it is up
to the programmer to elaborate declarations in an appropriate order. For
example writing:
.. code-block:: ada
function One return Float;
Q : Float := One;
function One return Float is
begin
return 1.0;
end One;
will obviously raise `Program_Error` at run time, because function
One will be called before its body is elaborated. In this case GNAT will
generate a warning that the call will raise `Program_Error`::
1. procedure y is
2. function One return Float;
3.
4. Q : Float := One;
|
>>> warning: cannot call "One" before body is elaborated
>>> warning: Program_Error will be raised at run time
5.
6. function One return Float is
7. begin
8. return 1.0;
9. end One;
10.
11. begin
12. null;
13. end;
Note that in this particular case, it is likely that the call is safe, because
the function `One` does not access any global variables.
Nevertheless in Ada, we do not want the validity of the check to depend on
the contents of the body (think about the separate compilation case), so this
is still wrong, as we discussed in the previous sections.
The error is easily corrected by rearranging the declarations so that the
body of `One` appears before the declaration containing the call
(note that in Ada 95 as well as later versions of the Ada standard,
declarations can appear in any order, so there is no restriction that
would prevent this reordering, and if we write:
.. code-block:: ada
function One return Float;
function One return Float is
begin
return 1.0;
end One;
Q : Float := One;
then all is well, no warning is generated, and no
`Program_Error` exception
will be raised.
Things are more complicated when a chain of subprograms is executed:
.. code-block:: ada
function A return Integer;
function B return Integer;
function C return Integer;
function B return Integer is begin return A; end;
function C return Integer is begin return B; end;
X : Integer := C;
function A return Integer is begin return 1; end;
Now the call to `C`
at elaboration time in the declaration of `X` is correct, because
the body of `C` is already elaborated,
and the call to `B` within the body of
`C` is correct, but the call
to `A` within the body of `B` is incorrect, because the body
of `A` has not been elaborated, so `Program_Error`
will be raised on the call to `A`.
In this case GNAT will generate a
warning that `Program_Error` may be
raised at the point of the call. Let's look at the warning::
1. procedure x is
2. function A return Integer;
3. function B return Integer;
4. function C return Integer;
5.
6. function B return Integer is begin return A; end;
|
>>> warning: call to "A" before body is elaborated may
raise Program_Error
>>> warning: "B" called at line 7
>>> warning: "C" called at line 9
7. function C return Integer is begin return B; end;
8.
9. X : Integer := C;
10.
11. function A return Integer is begin return 1; end;
12.
13. begin
14. null;
15. end;
Note that the message here says 'may raise', instead of the direct case,
where the message says 'will be raised'. That's because whether
`A` is
actually called depends in general on run-time flow of control.
For example, if the body of `B` said
.. code-block:: ada
function B return Integer is
begin
if some-condition-depending-on-input-data then
return A;
else
return 1;
end if;
end B;
then we could not know until run time whether the incorrect call to A would
actually occur, so `Program_Error` might
or might not be raised. It is possible for a compiler to
do a better job of analyzing bodies, to
determine whether or not `Program_Error`
might be raised, but it certainly
couldn't do a perfect job (that would require solving the halting problem
and is provably impossible), and because this is a warning anyway, it does
not seem worth the effort to do the analysis. Cases in which it
would be relevant are rare.
In practice, warnings of either of the forms given
above will usually correspond to
real errors, and should be examined carefully and eliminated.
In the rare case where a warning is bogus, it can be suppressed by any of
the following methods:
* Compile with the *-gnatws* switch set
* Suppress `Elaboration_Check` for the called subprogram
* Use pragma `Warnings_Off` to turn warnings off for the call
For the internal elaboration check case,
GNAT by default generates the
necessary run-time checks to ensure
that `Program_Error` is raised if any
call fails an elaboration check. Of course this can only happen if a
warning has been issued as described above. The use of pragma
`Suppress (Elaboration_Check)` may (but is not guaranteed to) suppress
some of these checks, meaning that it may be possible (but is not
guaranteed) for a program to be able to call a subprogram whose body
is not yet elaborated, without raising a `Program_Error` exception.
.. _Controlling_Elaboration_in_GNAT_-_External_Calls:
Controlling Elaboration in GNAT - External Calls
================================================
The previous section discussed the case in which the execution of a
particular thread of elaboration code occurred entirely within a
single unit. This is the easy case to handle, because a programmer
has direct and total control over the order of elaboration, and
furthermore, checks need only be generated in cases which are rare
and which the compiler can easily detect.
The situation is more complex when separate compilation is taken into account.
Consider the following:
.. code-block:: ada
package Math is
function Sqrt (Arg : Float) return Float;
end Math;
package body Math is
function Sqrt (Arg : Float) return Float is
begin
...
end Sqrt;
end Math;
with Math;
package Stuff is
X : Float := Math.Sqrt (0.5);
end Stuff;
with Stuff;
procedure Main is
begin
...
end Main;
where `Main` is the main program. When this program is executed, the
elaboration code must first be executed, and one of the jobs of the
binder is to determine the order in which the units of a program are
to be elaborated. In this case we have four units: the spec and body
of `Math`,
the spec of `Stuff` and the body of `Main`).
In what order should the four separate sections of elaboration code
be executed?
There are some restrictions in the order of elaboration that the binder
can choose. In particular, if unit U has a |with|
for a package `X`, then you
are assured that the spec of `X`
is elaborated before U , but you are
not assured that the body of `X`
is elaborated before U.
This means that in the above case, the binder is allowed to choose the
order::
spec of Math
spec of Stuff
body of Math
body of Main
but that's not good, because now the call to `Math.Sqrt`
that happens during
the elaboration of the `Stuff`
spec happens before the body of `Math.Sqrt` is
elaborated, and hence causes `Program_Error` exception to be raised.
At first glance, one might say that the binder is misbehaving, because
obviously you want to elaborate the body of something you |with| first, but
that is not a general rule that can be followed in all cases. Consider
.. code-block:: ada
package X is ...
package Y is ...
with X;
package body Y is ...
with Y;
package body X is ...
This is a common arrangement, and, apart from the order of elaboration
problems that might arise in connection with elaboration code, this works fine.
A rule that says that you must first elaborate the body of anything you
|with| cannot work in this case:
the body of `X` |withs| `Y`,
which means you would have to
elaborate the body of `Y` first, but that |withs| `X`,
which means
you have to elaborate the body of `X` first, but ... and we have a
loop that cannot be broken.
It is true that the binder can in many cases guess an order of elaboration
that is unlikely to cause a `Program_Error`
exception to be raised, and it tries to do so (in the
above example of `Math/Stuff/Spec`, the GNAT binder will
by default
elaborate the body of `Math` right after its spec, so all will be well).
However, a program that blindly relies on the binder to be helpful can
get into trouble, as we discussed in the previous sections, so GNAT
provides a number of facilities for assisting the programmer in
developing programs that are robust with respect to elaboration order.
.. _Default_Behavior_in_GNAT_-_Ensuring_Safety:
Default Behavior in GNAT - Ensuring Safety
==========================================
The default behavior in GNAT ensures elaboration safety. In its
default mode GNAT implements the
rule we previously described as the right approach. Let's restate it:
*If a unit has elaboration code that can directly or indirectly make a
call to a subprogram in a |withed| unit, or instantiate a generic
package in a |withed| unit, then if the |withed| unit
does not have pragma `Pure` or `Preelaborate`, then the client should have an
`Elaborate_All` pragma for the |withed| unit.*
*In the case of instantiating a generic subprogram, it is always
sufficient to have only an `Elaborate` pragma for the
|withed| unit.*
By following this rule a client is assured that calls and instantiations
can be made without risk of an exception.
In this mode GNAT traces all calls that are potentially made from
elaboration code, and puts in any missing implicit `Elaborate`
and `Elaborate_All` pragmas.
The advantage of this approach is that no elaboration problems
are possible if the binder can find an elaboration order that is
consistent with these implicit `Elaborate` and
`Elaborate_All` pragmas. The
disadvantage of this approach is that no such order may exist.
If the binder does not generate any diagnostics, then it means that it has
found an elaboration order that is guaranteed to be safe. However, the binder
may still be relying on implicitly generated `Elaborate` and
`Elaborate_All` pragmas so portability to other compilers than GNAT is not
guaranteed.
If it is important to guarantee portability, then the compilations should
use the *-gnatel*
(info messages for elaboration pragmas) switch. This will cause info messages
to be generated indicating the missing `Elaborate` and
`Elaborate_All` pragmas.
Consider the following source program:
.. code-block:: ada
with k;
package j is
m : integer := k.r;
end;
where it is clear that there
should be a pragma `Elaborate_All`
for unit `k`. An implicit pragma will be generated, and it is
likely that the binder will be able to honor it. However, if you want
to port this program to some other Ada compiler than GNAT.
it is safer to include the pragma explicitly in the source. If this
unit is compiled with the *-gnatel*
switch, then the compiler outputs an information message::
1. with k;
2. package j is
3. m : integer := k.r;
|
>>> info: call to "r" may raise Program_Error
>>> info: missing pragma Elaborate_All for "k"
4. end;
and these messages can be used as a guide for supplying manually
the missing pragmas. It is usually a bad idea to use this
option during development. That's because it will tell you when
you need to put in a pragma, but cannot tell you when it is time
to take it out. So the use of pragma `Elaborate_All` may lead to
unnecessary dependencies and even false circularities.
This default mode is more restrictive than the Ada Reference
Manual, and it is possible to construct programs which will compile
using the dynamic model described there, but will run into a
circularity using the safer static model we have described.
Of course any Ada compiler must be able to operate in a mode
consistent with the requirements of the Ada Reference Manual,
and in particular must have the capability of implementing the
standard dynamic model of elaboration with run-time checks.
In GNAT, this standard mode can be achieved either by the use of
the *-gnatE* switch on the compiler (*gcc* or
*gnatmake*) command, or by the use of the configuration pragma:
.. code-block:: ada
pragma Elaboration_Checks (DYNAMIC);
Either approach will cause the unit affected to be compiled using the
standard dynamic run-time elaboration checks described in the Ada
Reference Manual. The static model is generally preferable, since it
is clearly safer to rely on compile and link time checks rather than
run-time checks. However, in the case of legacy code, it may be
difficult to meet the requirements of the static model. This
issue is further discussed in
:ref:`What_to_Do_If_the_Default_Elaboration_Behavior_Fails`.
Note that the static model provides a strict subset of the allowed
behavior and programs of the Ada Reference Manual, so if you do
adhere to the static model and no circularities exist,
then you are assured that your program will
work using the dynamic model, providing that you remove any
pragma Elaborate statements from the source.
.. _Treatment_of_Pragma_Elaborate:
Treatment of Pragma Elaborate
=============================
.. index:: Pragma Elaborate
The use of `pragma Elaborate`
should generally be avoided in Ada 95 and Ada 2005 programs,
since there is no guarantee that transitive calls
will be properly handled. Indeed at one point, this pragma was placed
in Annex J (Obsolescent Features), on the grounds that it is never useful.
Now that's a bit restrictive. In practice, the case in which
`pragma Elaborate` is useful is when the caller knows that there
are no transitive calls, or that the called unit contains all necessary
transitive `pragma Elaborate` statements, and legacy code often
contains such uses.
Strictly speaking the static mode in GNAT should ignore such pragmas,
since there is no assurance at compile time that the necessary safety
conditions are met. In practice, this would cause GNAT to be incompatible
with correctly written Ada 83 code that had all necessary
`pragma Elaborate` statements in place. Consequently, we made the
decision that GNAT in its default mode will believe that if it encounters
a `pragma Elaborate` then the programmer knows what they are doing,
and it will trust that no elaboration errors can occur.
The result of this decision is two-fold. First to be safe using the
static mode, you should remove all `pragma Elaborate` statements.
Second, when fixing circularities in existing code, you can selectively
use `pragma Elaborate` statements to convince the static mode of
GNAT that it need not generate an implicit `pragma Elaborate_All`
statement.
When using the static mode with *-gnatwl*, any use of
`pragma Elaborate` will generate a warning about possible
problems.
.. _Elaboration_Issues_for_Library_Tasks:
Elaboration Issues for Library Tasks
====================================
.. index:: Library tasks, elaboration issues
.. index:: Elaboration of library tasks
In this section we examine special elaboration issues that arise for
programs that declare library level tasks.
Generally the model of execution of an Ada program is that all units are
elaborated, and then execution of the program starts. However, the
declaration of library tasks definitely does not fit this model. The
reason for this is that library tasks start as soon as they are declared
(more precisely, as soon as the statement part of the enclosing package
body is reached), that is to say before elaboration
of the program is complete. This means that if such a task calls a
subprogram, or an entry in another task, the callee may or may not be
elaborated yet, and in the standard
Reference Manual model of dynamic elaboration checks, you can even
get timing dependent Program_Error exceptions, since there can be
a race between the elaboration code and the task code.
The static model of elaboration in GNAT seeks to avoid all such
dynamic behavior, by being conservative, and the conservative
approach in this particular case is to assume that all the code
in a task body is potentially executed at elaboration time if
a task is declared at the library level.
This can definitely result in unexpected circularities. Consider
the following example
.. code-block:: ada
package Decls is
task Lib_Task is
entry Start;
end Lib_Task;
type My_Int is new Integer;
function Ident (M : My_Int) return My_Int;
end Decls;
with Utils;
package body Decls is
task body Lib_Task is
begin
accept Start;
Utils.Put_Val (2);
end Lib_Task;
function Ident (M : My_Int) return My_Int is
begin
return M;
end Ident;
end Decls;
with Decls;
package Utils is
procedure Put_Val (Arg : Decls.My_Int);
end Utils;
with Text_IO;
package body Utils is
procedure Put_Val (Arg : Decls.My_Int) is
begin
Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg)));
end Put_Val;
end Utils;
with Decls;
procedure Main is
begin
Decls.Lib_Task.Start;
end;
If the above example is compiled in the default static elaboration
mode, then a circularity occurs. The circularity comes from the call
`Utils.Put_Val` in the task body of `Decls.Lib_Task`. Since
this call occurs in elaboration code, we need an implicit pragma
`Elaborate_All` for `Utils`. This means that not only must
the spec and body of `Utils` be elaborated before the body
of `Decls`, but also the spec and body of any unit that is
|withed| by the body of `Utils` must also be elaborated before
the body of `Decls`. This is the transitive implication of
pragma `Elaborate_All` and it makes sense, because in general
the body of `Put_Val` might have a call to something in a
|withed| unit.
In this case, the body of Utils (actually its spec) |withs|
`Decls`. Unfortunately this means that the body of `Decls`
must be elaborated before itself, in case there is a call from the
body of `Utils`.
Here is the exact chain of events we are worrying about:
* In the body of `Decls` a call is made from within the body of a library
task to a subprogram in the package `Utils`. Since this call may
occur at elaboration time (given that the task is activated at elaboration
time), we have to assume the worst, i.e., that the
call does happen at elaboration time.
* This means that the body and spec of `Util` must be elaborated before
the body of `Decls` so that this call does not cause an access before
elaboration.
* Within the body of `Util`, specifically within the body of
`Util.Put_Val` there may be calls to any unit |withed|
by this package.
* One such |withed| package is package `Decls`, so there
might be a call to a subprogram in `Decls` in `Put_Val`.
In fact there is such a call in this example, but we would have to
assume that there was such a call even if it were not there, since
we are not supposed to write the body of `Decls` knowing what
is in the body of `Utils`; certainly in the case of the
static elaboration model, the compiler does not know what is in
other bodies and must assume the worst.
* This means that the spec and body of `Decls` must also be
elaborated before we elaborate the unit containing the call, but
that unit is `Decls`! This means that the body of `Decls`
must be elaborated before itself, and that's a circularity.
Indeed, if you add an explicit pragma `Elaborate_All` for `Utils` in
the body of `Decls` you will get a true Ada Reference Manual
circularity that makes the program illegal.
In practice, we have found that problems with the static model of
elaboration in existing code often arise from library tasks, so
we must address this particular situation.
Note that if we compile and run the program above, using the dynamic model of
elaboration (that is to say use the *-gnatE* switch),
then it compiles, binds,
links, and runs, printing the expected result of 2. Therefore in some sense
the circularity here is only apparent, and we need to capture
the properties of this program that distinguish it from other library-level
tasks that have real elaboration problems.
We have four possible answers to this question:
* Use the dynamic model of elaboration.
If we use the *-gnatE* switch, then as noted above, the program works.
Why is this? If we examine the task body, it is apparent that the task cannot
proceed past the
`accept` statement until after elaboration has been completed, because
the corresponding entry call comes from the main program, not earlier.
This is why the dynamic model works here. But that's really giving
up on a precise analysis, and we prefer to take this approach only if we cannot
solve the
problem in any other manner. So let us examine two ways to reorganize
the program to avoid the potential elaboration problem.
* Split library tasks into separate packages.
Write separate packages, so that library tasks are isolated from
other declarations as much as possible. Let us look at a variation on
the above program.
.. code-block:: ada
package Decls1 is
task Lib_Task is
entry Start;
end Lib_Task;
end Decls1;
with Utils;
package body Decls1 is
task body Lib_Task is
begin
accept Start;
Utils.Put_Val (2);
end Lib_Task;
end Decls1;
package Decls2 is
type My_Int is new Integer;
function Ident (M : My_Int) return My_Int;
end Decls2;
with Utils;
package body Decls2 is
function Ident (M : My_Int) return My_Int is
begin
return M;
end Ident;
end Decls2;
with Decls2;
package Utils is
procedure Put_Val (Arg : Decls2.My_Int);
end Utils;
with Text_IO;
package body Utils is
procedure Put_Val (Arg : Decls2.My_Int) is
begin
Text_IO.Put_Line (Decls2.My_Int'Image (Decls2.Ident (Arg)));
end Put_Val;
end Utils;
with Decls1;
procedure Main is
begin
Decls1.Lib_Task.Start;
end;
All we have done is to split `Decls` into two packages, one
containing the library task, and one containing everything else. Now
there is no cycle, and the program compiles, binds, links and executes
using the default static model of elaboration.
* Declare separate task types.
A significant part of the problem arises because of the use of the
single task declaration form. This means that the elaboration of
the task type, and the elaboration of the task itself (i.e., the
creation of the task) happen at the same time. A good rule
of style in Ada is to always create explicit task types. By
following the additional step of placing task objects in separate
packages from the task type declaration, many elaboration problems
are avoided. Here is another modified example of the example program:
.. code-block:: ada
package Decls is
task type Lib_Task_Type is
entry Start;
end Lib_Task_Type;
type My_Int is new Integer;
function Ident (M : My_Int) return My_Int;
end Decls;
with Utils;
package body Decls is
task body Lib_Task_Type is
begin
accept Start;
Utils.Put_Val (2);
end Lib_Task_Type;
function Ident (M : My_Int) return My_Int is
begin
return M;
end Ident;
end Decls;
with Decls;
package Utils is
procedure Put_Val (Arg : Decls.My_Int);
end Utils;
with Text_IO;
package body Utils is
procedure Put_Val (Arg : Decls.My_Int) is
begin
Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg)));
end Put_Val;
end Utils;
with Decls;
package Declst is
Lib_Task : Decls.Lib_Task_Type;
end Declst;
with Declst;
procedure Main is
begin
Declst.Lib_Task.Start;
end;
What we have done here is to replace the `task` declaration in
package `Decls` with a `task type` declaration. Then we
introduce a separate package `Declst` to contain the actual
task object. This separates the elaboration issues for
the `task type`
declaration, which causes no trouble, from the elaboration issues
of the task object, which is also unproblematic, since it is now independent
of the elaboration of `Utils`.
This separation of concerns also corresponds to
a generally sound engineering principle of separating declarations
from instances. This version of the program also compiles, binds, links,
and executes, generating the expected output.
.. index:: No_Entry_Calls_In_Elaboration_Code restriction
* Use No_Entry_Calls_In_Elaboration_Code restriction.
The previous two approaches described how a program can be restructured
to avoid the special problems caused by library task bodies. in practice,
however, such restructuring may be difficult to apply to existing legacy code,
so we must consider solutions that do not require massive rewriting.
Let us consider more carefully why our original sample program works
under the dynamic model of elaboration. The reason is that the code
in the task body blocks immediately on the `accept`
statement. Now of course there is nothing to prohibit elaboration
code from making entry calls (for example from another library level task),
so we cannot tell in isolation that
the task will not execute the accept statement during elaboration.
However, in practice it is very unusual to see elaboration code
make any entry calls, and the pattern of tasks starting
at elaboration time and then immediately blocking on `accept` or
`select` statements is very common. What this means is that
the compiler is being too pessimistic when it analyzes the
whole package body as though it might be executed at elaboration
time.
If we know that the elaboration code contains no entry calls, (a very safe
assumption most of the time, that could almost be made the default
behavior), then we can compile all units of the program under control
of the following configuration pragma:
.. code-block:: ada
pragma Restrictions (No_Entry_Calls_In_Elaboration_Code);
This pragma can be placed in the :file:`gnat.adc` file in the usual
manner. If we take our original unmodified program and compile it
in the presence of a :file:`gnat.adc` containing the above pragma,
then once again, we can compile, bind, link, and execute, obtaining
the expected result. In the presence of this pragma, the compiler does
not trace calls in a task body, that appear after the first `accept`
or `select` statement, and therefore does not report a potential
circularity in the original program.
The compiler will check to the extent it can that the above
restriction is not violated, but it is not always possible to do a
complete check at compile time, so it is important to use this
pragma only if the stated restriction is in fact met, that is to say
no task receives an entry call before elaboration of all units is completed.
.. _Mixing_Elaboration_Models:
Mixing Elaboration Models
=========================
So far, we have assumed that the entire program is either compiled
using the dynamic model or static model, ensuring consistency. It
is possible to mix the two models, but rules have to be followed
if this mixing is done to ensure that elaboration checks are not
omitted.
The basic rule is that
**a unit compiled with the static model cannot
be |withed| by a unit compiled with the dynamic model**.
The reason for this is that in the static model, a unit assumes that
its clients guarantee to use (the equivalent of) pragma
`Elaborate_All` so that no elaboration checks are required
in inner subprograms, and this assumption is violated if the
client is compiled with dynamic checks.
The precise rule is as follows. A unit that is compiled with dynamic
checks can only |with| a unit that meets at least one of the
following criteria:
* The |withed| unit is itself compiled with dynamic elaboration
checks (that is with the *-gnatE* switch.
* The |withed| unit is an internal GNAT implementation unit from
the System, Interfaces, Ada, or GNAT hierarchies.
* The |withed| unit has pragma Preelaborate or pragma Pure.
* The |withing| unit (that is the client) has an explicit pragma
`Elaborate_All` for the |withed| unit.
If this rule is violated, that is if a unit with dynamic elaboration
checks |withs| a unit that does not meet one of the above four
criteria, then the binder (`gnatbind`) will issue a warning
similar to that in the following example::
warning: "x.ads" has dynamic elaboration checks and with's
warning: "y.ads" which has static elaboration checks
These warnings indicate that the rule has been violated, and that as a result
elaboration checks may be missed in the resulting executable file.
This warning may be suppressed using the *-ws* binder switch
in the usual manner.
One useful application of this mixing rule is in the case of a subsystem
which does not itself |with| units from the remainder of the
application. In this case, the entire subsystem can be compiled with
dynamic checks to resolve a circularity in the subsystem, while
allowing the main application that uses this subsystem to be compiled
using the more reliable default static model.
.. _What_to_Do_If_the_Default_Elaboration_Behavior_Fails:
What to Do If the Default Elaboration Behavior Fails
====================================================
If the binder cannot find an acceptable order, it outputs detailed
diagnostics. For example::
error: elaboration circularity detected
info: "proc (body)" must be elaborated before "pack (body)"
info: reason: Elaborate_All probably needed in unit "pack (body)"
info: recompile "pack (body)" with -gnatel
info: for full details
info: "proc (body)"
info: is needed by its spec:
info: "proc (spec)"
info: which is withed by:
info: "pack (body)"
info: "pack (body)" must be elaborated before "proc (body)"
info: reason: pragma Elaborate in unit "proc (body)"
In this case we have a cycle that the binder cannot break. On the one
hand, there is an explicit pragma Elaborate in `proc` for
`pack`. This means that the body of `pack` must be elaborated
before the body of `proc`. On the other hand, there is elaboration
code in `pack` that calls a subprogram in `proc`. This means
that for maximum safety, there should really be a pragma
Elaborate_All in `pack` for `proc` which would require that
the body of `proc` be elaborated before the body of
`pack`. Clearly both requirements cannot be satisfied.
Faced with a circularity of this kind, you have three different options.
* *Fix the program*
The most desirable option from the point of view of long-term maintenance
is to rearrange the program so that the elaboration problems are avoided.
One useful technique is to place the elaboration code into separate
child packages. Another is to move some of the initialization code to
explicitly called subprograms, where the program controls the order
of initialization explicitly. Although this is the most desirable option,
it may be impractical and involve too much modification, especially in
the case of complex legacy code.
* *Perform dynamic checks*
If the compilations are done using the *-gnatE*
(dynamic elaboration check) switch, then GNAT behaves in a quite different
manner. Dynamic checks are generated for all calls that could possibly result
in raising an exception. With this switch, the compiler does not generate
implicit `Elaborate` or `Elaborate_All` pragmas. The behavior then is
exactly as specified in the :title:`Ada Reference Manual`.
The binder will generate
an executable program that may or may not raise `Program_Error`, and then
it is the programmer's job to ensure that it does not raise an exception. Note
that it is important to compile all units with the switch, it cannot be used
selectively.
* *Suppress checks*
The drawback of dynamic checks is that they generate a
significant overhead at run time, both in space and time. If you
are absolutely sure that your program cannot raise any elaboration
exceptions, and you still want to use the dynamic elaboration model,
then you can use the configuration pragma
`Suppress (Elaboration_Check)` to suppress all such checks. For
example this pragma could be placed in the :file:`gnat.adc` file.
* *Suppress checks selectively*
When you know that certain calls or instantiations in elaboration code cannot
possibly lead to an elaboration error, and the binder nevertheless complains
about implicit `Elaborate` and `Elaborate_All` pragmas that lead to
elaboration circularities, it is possible to remove those warnings locally and
obtain a program that will bind. Clearly this can be unsafe, and it is the
responsibility of the programmer to make sure that the resulting program has no
elaboration anomalies. The pragma `Suppress (Elaboration_Check)` can be
used with different granularity to suppress warnings and break elaboration
circularities:
* Place the pragma that names the called subprogram in the declarative part
that contains the call.
* Place the pragma in the declarative part, without naming an entity. This
disables warnings on all calls in the corresponding declarative region.
* Place the pragma in the package spec that declares the called subprogram,
and name the subprogram. This disables warnings on all elaboration calls to
that subprogram.
* Place the pragma in the package spec that declares the called subprogram,
without naming any entity. This disables warnings on all elaboration calls to
all subprograms declared in this spec.
* Use Pragma Elaborate.
As previously described in section :ref:`Treatment_of_Pragma_Elaborate`,
GNAT in static mode assumes that a `pragma` Elaborate indicates correctly
that no elaboration checks are required on calls to the designated unit.
There may be cases in which the caller knows that no transitive calls
can occur, so that a `pragma Elaborate` will be sufficient in a
case where `pragma Elaborate_All` would cause a circularity.
These five cases are listed in order of decreasing safety, and therefore
require increasing programmer care in their application. Consider the
following program:
.. code-block:: ada
package Pack1 is
function F1 return Integer;
X1 : Integer;
end Pack1;
package Pack2 is
function F2 return Integer;
function Pure (x : integer) return integer;
-- pragma Suppress (Elaboration_Check, On => Pure); -- (3)
-- pragma Suppress (Elaboration_Check); -- (4)
end Pack2;
with Pack2;
package body Pack1 is
function F1 return Integer is
begin
return 100;
end F1;
Val : integer := Pack2.Pure (11); -- Elab. call (1)
begin
declare
-- pragma Suppress(Elaboration_Check, Pack2.F2); -- (1)
-- pragma Suppress(Elaboration_Check); -- (2)
begin
X1 := Pack2.F2 + 1; -- Elab. call (2)
end;
end Pack1;
with Pack1;
package body Pack2 is
function F2 return Integer is
begin
return Pack1.F1;
end F2;
function Pure (x : integer) return integer is
begin
return x ** 3 - 3 * x;
end;
end Pack2;
with Pack1, Ada.Text_IO;
procedure Proc3 is
begin
Ada.Text_IO.Put_Line(Pack1.X1'Img); -- 101
end Proc3;
In the absence of any pragmas, an attempt to bind this program produces
the following diagnostics::
error: elaboration circularity detected
info: "pack1 (body)" must be elaborated before "pack1 (body)"
info: reason: Elaborate_All probably needed in unit "pack1 (body)"
info: recompile "pack1 (body)" with -gnatel for full details
info: "pack1 (body)"
info: must be elaborated along with its spec:
info: "pack1 (spec)"
info: which is withed by:
info: "pack2 (body)"
info: which must be elaborated along with its spec:
info: "pack2 (spec)"
info: which is withed by:
info: "pack1 (body)"
The sources of the circularity are the two calls to `Pack2.Pure` and
`Pack2.F2` in the body of `Pack1`. We can see that the call to
F2 is safe, even though F2 calls F1, because the call appears after the
elaboration of the body of F1. Therefore the pragma (1) is safe, and will
remove the warning on the call. It is also possible to use pragma (2)
because there are no other potentially unsafe calls in the block.
The call to `Pure` is safe because this function does not depend on the
state of `Pack2`. Therefore any call to this function is safe, and it
is correct to place pragma (3) in the corresponding package spec.
Finally, we could place pragma (4) in the spec of `Pack2` to disable
warnings on all calls to functions declared therein. Note that this is not
necessarily safe, and requires more detailed examination of the subprogram
bodies involved. In particular, a call to `F2` requires that `F1`
be already elaborated.
It is hard to generalize on which of these four approaches should be
taken. Obviously if it is possible to fix the program so that the default
treatment works, this is preferable, but this may not always be practical.
It is certainly simple enough to use *-gnatE*
but the danger in this case is that, even if the GNAT binder
finds a correct elaboration order, it may not always do so,
and certainly a binder from another Ada compiler might not. A
combination of testing and analysis (for which the
information messages generated with the *-gnatel*
switch can be useful) must be used to ensure that the program is free
of errors. One switch that is useful in this testing is the
*-p (pessimistic elaboration order)* switch for `gnatbind`.
Normally the binder tries to find an order that has the best chance
of avoiding elaboration problems. However, if this switch is used, the binder
plays a devil's advocate role, and tries to choose the order that
has the best chance of failing. If your program works even with this
switch, then it has a better chance of being error free, but this is still
not a guarantee.
For an example of this approach in action, consider the C-tests (executable
tests) from the ACATS suite. If these are compiled and run with the default
treatment, then all but one of them succeed without generating any error
diagnostics from the binder. However, there is one test that fails, and
this is not surprising, because the whole point of this test is to ensure
that the compiler can handle cases where it is impossible to determine
a correct order statically, and it checks that an exception is indeed
raised at run time.
This one test must be compiled and run using the *-gnatE*
switch, and then it passes. Alternatively, the entire suite can
be run using this switch. It is never wrong to run with the dynamic
elaboration switch if your code is correct, and we assume that the
C-tests are indeed correct (it is less efficient, but efficiency is
not a factor in running the ACATS tests.)
.. _Elaboration_for_Indirect_Calls:
Elaboration for Indirect Calls
==============================
.. index:: Dispatching calls
.. index:: Indirect calls
In rare cases, the static elaboration model fails to prevent
dispatching calls to not-yet-elaborated subprograms. In such cases, we
fall back to run-time checks; premature calls to any primitive
operation of a tagged type before the body of the operation has been
elaborated will raise `Program_Error`.
Access-to-subprogram types, however, are handled conservatively, and
do not require run-time checks. This was not true in earlier versions
of the compiler; you can use the *-gnatd.U* debug switch to
revert to the old behavior if the new conservative behavior causes
elaboration cycles. Here, 'conservative' means that if you do
`P'Access` during elaboration, the compiler will assume that you
might call `P` indirectly during elaboration, so it adds an
implicit `pragma Elaborate_All` on the library unit containing
`P`. The *-gnatd.U* switch is safe if you know there are
no such calls. If the program worked before, it will continue to work
with *-gnatd.U*. But beware that code modifications such as
adding an indirect call can cause erroneous behavior in the presence
of *-gnatd.U*.
.. _Summary_of_Procedures_for_Elaboration_Control:
Summary of Procedures for Elaboration Control
=============================================
.. index:: Elaboration control
First, compile your program with the default options, using none of
the special elaboration control switches. If the binder successfully
binds your program, then you can be confident that, apart from issues
raised by the use of access-to-subprogram types and dynamic dispatching,
the program is free of elaboration errors. If it is important that the
program be portable to other compilers than GNAT, then use the
*-gnatel*
switch to generate messages about missing `Elaborate` or
`Elaborate_All` pragmas, and supply the missing pragmas.
If the program fails to bind using the default static elaboration
handling, then you can fix the program to eliminate the binder
message, or recompile the entire program with the
*-gnatE* switch to generate dynamic elaboration checks,
and, if you are sure there really are no elaboration problems,
use a global pragma `Suppress (Elaboration_Check)`.
.. _Other_Elaboration_Order_Considerations:
Other Elaboration Order Considerations
======================================
This section has been entirely concerned with the issue of finding a valid
elaboration order, as defined by the Ada Reference Manual. In a case
where several elaboration orders are valid, the task is to find one
of the possible valid elaboration orders (and the static model in GNAT
will ensure that this is achieved).
The purpose of the elaboration rules in the Ada Reference Manual is to
make sure that no entity is accessed before it has been elaborated. For
a subprogram, this means that the spec and body must have been elaborated
before the subprogram is called. For an object, this means that the object
must have been elaborated before its value is read or written. A violation
of either of these two requirements is an access before elaboration order,
and this section has been all about avoiding such errors.
In the case where more than one order of elaboration is possible, in the
sense that access before elaboration errors are avoided, then any one of
the orders is 'correct' in the sense that it meets the requirements of
the Ada Reference Manual, and no such error occurs.
However, it may be the case for a given program, that there are
constraints on the order of elaboration that come not from consideration
of avoiding elaboration errors, but rather from extra-lingual logic
requirements. Consider this example:
.. code-block:: ada
with Init_Constants;
package Constants is
X : Integer := 0;
Y : Integer := 0;
end Constants;
package Init_Constants is
procedure P; --* require a body*
end Init_Constants;
with Constants;
package body Init_Constants is
procedure P is begin null; end;
begin
Constants.X := 3;
Constants.Y := 4;
end Init_Constants;
with Constants;
package Calc is
Z : Integer := Constants.X + Constants.Y;
end Calc;
with Calc;
with Text_IO; use Text_IO;
procedure Main is
begin
Put_Line (Calc.Z'Img);
end Main;
In this example, there is more than one valid order of elaboration. For
example both the following are correct orders::
Init_Constants spec
Constants spec
Calc spec
Init_Constants body
Main body
and
::
Init_Constants spec
Init_Constants body
Constants spec
Calc spec
Main body
There is no language rule to prefer one or the other, both are correct
from an order of elaboration point of view. But the programmatic effects
of the two orders are very different. In the first, the elaboration routine
of `Calc` initializes `Z` to zero, and then the main program
runs with this value of zero. But in the second order, the elaboration
routine of `Calc` runs after the body of Init_Constants has set
`X` and `Y` and thus `Z` is set to 7 before `Main` runs.
One could perhaps by applying pretty clever non-artificial intelligence
to the situation guess that it is more likely that the second order of
elaboration is the one desired, but there is no formal linguistic reason
to prefer one over the other. In fact in this particular case, GNAT will
prefer the second order, because of the rule that bodies are elaborated
as soon as possible, but it's just luck that this is what was wanted
(if indeed the second order was preferred).
If the program cares about the order of elaboration routines in a case like
this, it is important to specify the order required. In this particular
case, that could have been achieved by adding to the spec of Calc:
.. code-block:: ada
pragma Elaborate_All (Constants);
which requires that the body (if any) and spec of `Constants`,
as well as the body and spec of any unit |withed| by
`Constants` be elaborated before `Calc` is elaborated.
Clearly no automatic method can always guess which alternative you require,
and if you are working with legacy code that had constraints of this kind
which were not properly specified by adding `Elaborate` or
`Elaborate_All` pragmas, then indeed it is possible that two different
compilers can choose different orders.
However, GNAT does attempt to diagnose the common situation where there
are uninitialized variables in the visible part of a package spec, and the
corresponding package body has an elaboration block that directly or
indirectly initialized one or more of these variables. This is the situation
in which a pragma Elaborate_Body is usually desirable, and GNAT will generate
a warning that suggests this addition if it detects this situation.
The `gnatbind` *-p* switch may be useful in smoking
out problems. This switch causes bodies to be elaborated as late as possible
instead of as early as possible. In the example above, it would have forced
the choice of the first elaboration order. If you get different results
when using this switch, and particularly if one set of results is right,
and one is wrong as far as you are concerned, it shows that you have some
missing `Elaborate` pragmas. For the example above, we have the
following output:
.. code-block:: sh
$ gnatmake -f -q main
$ main
7
$ gnatmake -f -q main -bargs -p
$ main
0
It is of course quite unlikely that both these results are correct, so
it is up to you in a case like this to investigate the source of the
difference, by looking at the two elaboration orders that are chosen,
and figuring out which is correct, and then adding the necessary
`Elaborate` or `Elaborate_All` pragmas to ensure the desired order.
.. _Determining_the_Chosen_Elaboration_Order:
Determining the Chosen Elaboration Order
========================================
To see the elaboration order that the binder chooses, you can look at
the last part of the file:`b~xxx.adb` binder output file. Here is an example::
System.Soft_Links'Elab_Body;
E14 := True;
System.Secondary_Stack'Elab_Body;
E18 := True;
System.Exception_Table'Elab_Body;
E24 := True;
Ada.Io_Exceptions'Elab_Spec;
E67 := True;
Ada.Tags'Elab_Spec;
Ada.Streams'Elab_Spec;
E43 := True;
Interfaces.C'Elab_Spec;
E69 := True;
System.Finalization_Root'Elab_Spec;
E60 := True;
System.Os_Lib'Elab_Body;
E71 := True;
System.Finalization_Implementation'Elab_Spec;
System.Finalization_Implementation'Elab_Body;
E62 := True;
Ada.Finalization'Elab_Spec;
E58 := True;
Ada.Finalization.List_Controller'Elab_Spec;
E76 := True;
System.File_Control_Block'Elab_Spec;
E74 := True;
System.File_Io'Elab_Body;
E56 := True;
Ada.Tags'Elab_Body;
E45 := True;
Ada.Text_Io'Elab_Spec;
Ada.Text_Io'Elab_Body;
E07 := True;
Here Elab_Spec elaborates the spec
and Elab_Body elaborates the body. The assignments to the :samp:`E{xx}` flags
flag that the corresponding body is now elaborated.
You can also ask the binder to generate a more
readable list of the elaboration order using the
`-l` switch when invoking the binder. Here is
an example of the output generated by this switch::
ada (spec)
interfaces (spec)
system (spec)
system.case_util (spec)
system.case_util (body)
system.concat_2 (spec)
system.concat_2 (body)
system.concat_3 (spec)
system.concat_3 (body)
system.htable (spec)
system.parameters (spec)
system.parameters (body)
system.crtl (spec)
interfaces.c_streams (spec)
interfaces.c_streams (body)
system.restrictions (spec)
system.restrictions (body)
system.standard_library (spec)
system.exceptions (spec)
system.exceptions (body)
system.storage_elements (spec)
system.storage_elements (body)
system.secondary_stack (spec)
system.stack_checking (spec)
system.stack_checking (body)
system.string_hash (spec)
system.string_hash (body)
system.htable (body)
system.strings (spec)
system.strings (body)
system.traceback (spec)
system.traceback (body)
system.traceback_entries (spec)
system.traceback_entries (body)
ada.exceptions (spec)
ada.exceptions.last_chance_handler (spec)
system.soft_links (spec)
system.soft_links (body)
ada.exceptions.last_chance_handler (body)
system.secondary_stack (body)
system.exception_table (spec)
system.exception_table (body)
ada.io_exceptions (spec)
ada.tags (spec)
ada.streams (spec)
interfaces.c (spec)
interfaces.c (body)
system.finalization_root (spec)
system.finalization_root (body)
system.memory (spec)
system.memory (body)
system.standard_library (body)
system.os_lib (spec)
system.os_lib (body)
system.unsigned_types (spec)
system.stream_attributes (spec)
system.stream_attributes (body)
system.finalization_implementation (spec)
system.finalization_implementation (body)
ada.finalization (spec)
ada.finalization (body)
ada.finalization.list_controller (spec)
ada.finalization.list_controller (body)
system.file_control_block (spec)
system.file_io (spec)
system.file_io (body)
system.val_uns (spec)
system.val_util (spec)
system.val_util (body)
system.val_uns (body)
system.wch_con (spec)
system.wch_con (body)
system.wch_cnv (spec)
system.wch_jis (spec)
system.wch_jis (body)
system.wch_cnv (body)
system.wch_stw (spec)
system.wch_stw (body)
ada.tags (body)
ada.exceptions (body)
ada.text_io (spec)
ada.text_io (body)
text_io (spec)
gdbstr (body)
.. _Example_of_Binder_Output_File:
*****************************
Example of Binder Output File
*****************************
.. index:: Binder output (example)
This Appendix displays the source code for the output file
generated by *gnatbind* for a simple 'Hello World' program.
Comments have been added for clarification purposes.
.. code-block:: ada
-- The package is called Ada_Main unless this name is actually used
-- as a unit name in the partition, in which case some other unique
-- name is used.
pragma Ada_95;
with System;
package ada_main is
pragma Warnings (Off);
-- The main program saves the parameters (argument count,
-- argument values, environment pointer) in global variables
-- for later access by other units including
-- Ada.Command_Line.
gnat_argc : Integer;
gnat_argv : System.Address;
gnat_envp : System.Address;
-- The actual variables are stored in a library routine. This
-- is useful for some shared library situations, where there
-- are problems if variables are not in the library.
pragma Import (C, gnat_argc);
pragma Import (C, gnat_argv);
pragma Import (C, gnat_envp);
-- The exit status is similarly an external location
gnat_exit_status : Integer;
pragma Import (C, gnat_exit_status);
GNAT_Version : constant String :=
"GNAT Version: Pro 7.4.0w (20141119-49)" & ASCII.NUL;
pragma Export (C, GNAT_Version, "__gnat_version");
Ada_Main_Program_Name : constant String := "_ada_hello" & ASCII.NUL;
pragma Export (C, Ada_Main_Program_Name, "__gnat_ada_main_program_name");
-- This is the generated adainit routine that performs
-- initialization at the start of execution. In the case
-- where Ada is the main program, this main program makes
-- a call to adainit at program startup.
procedure adainit;
pragma Export (C, adainit, "adainit");
-- This is the generated adafinal routine that performs
-- finalization at the end of execution. In the case where
-- Ada is the main program, this main program makes a call
-- to adafinal at program termination.
procedure adafinal;
pragma Export (C, adafinal, "adafinal");
-- This routine is called at the start of execution. It is
-- a dummy routine that is used by the debugger to breakpoint
-- at the start of execution.
-- This is the actual generated main program (it would be
-- suppressed if the no main program switch were used). As
-- required by standard system conventions, this program has
-- the external name main.
function main
(argc : Integer;
argv : System.Address;
envp : System.Address)
return Integer;
pragma Export (C, main, "main");
-- The following set of constants give the version
-- identification values for every unit in the bound
-- partition. This identification is computed from all
-- dependent semantic units, and corresponds to the
-- string that would be returned by use of the
-- Body_Version or Version attributes.
-- The following Export pragmas export the version numbers
-- with symbolic names ending in B (for body) or S
-- (for spec) so that they can be located in a link. The
-- information provided here is sufficient to track down
-- the exact versions of units used in a given build.
type Version_32 is mod 2 ** 32;
u00001 : constant Version_32 := 16#8ad6e54a#;
pragma Export (C, u00001, "helloB");
u00002 : constant Version_32 := 16#fbff4c67#;
pragma Export (C, u00002, "system__standard_libraryB");
u00003 : constant Version_32 := 16#1ec6fd90#;
pragma Export (C, u00003, "system__standard_libraryS");
u00004 : constant Version_32 := 16#3ffc8e18#;
pragma Export (C, u00004, "adaS");
u00005 : constant Version_32 := 16#28f088c2#;
pragma Export (C, u00005, "ada__text_ioB");
u00006 : constant Version_32 := 16#f372c8ac#;
pragma Export (C, u00006, "ada__text_ioS");
u00007 : constant Version_32 := 16#2c143749#;
pragma Export (C, u00007, "ada__exceptionsB");
u00008 : constant Version_32 := 16#f4f0cce8#;
pragma Export (C, u00008, "ada__exceptionsS");
u00009 : constant Version_32 := 16#a46739c0#;
pragma Export (C, u00009, "ada__exceptions__last_chance_handlerB");
u00010 : constant Version_32 := 16#3aac8c92#;
pragma Export (C, u00010, "ada__exceptions__last_chance_handlerS");
u00011 : constant Version_32 := 16#1d274481#;
pragma Export (C, u00011, "systemS");
u00012 : constant Version_32 := 16#a207fefe#;
pragma Export (C, u00012, "system__soft_linksB");
u00013 : constant Version_32 := 16#467d9556#;
pragma Export (C, u00013, "system__soft_linksS");
u00014 : constant Version_32 := 16#b01dad17#;
pragma Export (C, u00014, "system__parametersB");
u00015 : constant Version_32 := 16#630d49fe#;
pragma Export (C, u00015, "system__parametersS");
u00016 : constant Version_32 := 16#b19b6653#;
pragma Export (C, u00016, "system__secondary_stackB");
u00017 : constant Version_32 := 16#b6468be8#;
pragma Export (C, u00017, "system__secondary_stackS");
u00018 : constant Version_32 := 16#39a03df9#;
pragma Export (C, u00018, "system__storage_elementsB");
u00019 : constant Version_32 := 16#30e40e85#;
pragma Export (C, u00019, "system__storage_elementsS");
u00020 : constant Version_32 := 16#41837d1e#;
pragma Export (C, u00020, "system__stack_checkingB");
u00021 : constant Version_32 := 16#93982f69#;
pragma Export (C, u00021, "system__stack_checkingS");
u00022 : constant Version_32 := 16#393398c1#;
pragma Export (C, u00022, "system__exception_tableB");
u00023 : constant Version_32 := 16#b33e2294#;
pragma Export (C, u00023, "system__exception_tableS");
u00024 : constant Version_32 := 16#ce4af020#;
pragma Export (C, u00024, "system__exceptionsB");
u00025 : constant Version_32 := 16#75442977#;
pragma Export (C, u00025, "system__exceptionsS");
u00026 : constant Version_32 := 16#37d758f1#;
pragma Export (C, u00026, "system__exceptions__machineS");
u00027 : constant Version_32 := 16#b895431d#;
pragma Export (C, u00027, "system__exceptions_debugB");
u00028 : constant Version_32 := 16#aec55d3f#;
pragma Export (C, u00028, "system__exceptions_debugS");
u00029 : constant Version_32 := 16#570325c8#;
pragma Export (C, u00029, "system__img_intB");
u00030 : constant Version_32 := 16#1ffca443#;
pragma Export (C, u00030, "system__img_intS");
u00031 : constant Version_32 := 16#b98c3e16#;
pragma Export (C, u00031, "system__tracebackB");
u00032 : constant Version_32 := 16#831a9d5a#;
pragma Export (C, u00032, "system__tracebackS");
u00033 : constant Version_32 := 16#9ed49525#;
pragma Export (C, u00033, "system__traceback_entriesB");
u00034 : constant Version_32 := 16#1d7cb2f1#;
pragma Export (C, u00034, "system__traceback_entriesS");
u00035 : constant Version_32 := 16#8c33a517#;
pragma Export (C, u00035, "system__wch_conB");
u00036 : constant Version_32 := 16#065a6653#;
pragma Export (C, u00036, "system__wch_conS");
u00037 : constant Version_32 := 16#9721e840#;
pragma Export (C, u00037, "system__wch_stwB");
u00038 : constant Version_32 := 16#2b4b4a52#;
pragma Export (C, u00038, "system__wch_stwS");
u00039 : constant Version_32 := 16#92b797cb#;
pragma Export (C, u00039, "system__wch_cnvB");
u00040 : constant Version_32 := 16#09eddca0#;
pragma Export (C, u00040, "system__wch_cnvS");
u00041 : constant Version_32 := 16#6033a23f#;
pragma Export (C, u00041, "interfacesS");
u00042 : constant Version_32 := 16#ece6fdb6#;
pragma Export (C, u00042, "system__wch_jisB");
u00043 : constant Version_32 := 16#899dc581#;
pragma Export (C, u00043, "system__wch_jisS");
u00044 : constant Version_32 := 16#10558b11#;
pragma Export (C, u00044, "ada__streamsB");
u00045 : constant Version_32 := 16#2e6701ab#;
pragma Export (C, u00045, "ada__streamsS");
u00046 : constant Version_32 := 16#db5c917c#;
pragma Export (C, u00046, "ada__io_exceptionsS");
u00047 : constant Version_32 := 16#12c8cd7d#;
pragma Export (C, u00047, "ada__tagsB");
u00048 : constant Version_32 := 16#ce72c228#;
pragma Export (C, u00048, "ada__tagsS");
u00049 : constant Version_32 := 16#c3335bfd#;
pragma Export (C, u00049, "system__htableB");
u00050 : constant Version_32 := 16#99e5f76b#;
pragma Export (C, u00050, "system__htableS");
u00051 : constant Version_32 := 16#089f5cd0#;
pragma Export (C, u00051, "system__string_hashB");
u00052 : constant Version_32 := 16#3bbb9c15#;
pragma Export (C, u00052, "system__string_hashS");
u00053 : constant Version_32 := 16#807fe041#;
pragma Export (C, u00053, "system__unsigned_typesS");
u00054 : constant Version_32 := 16#d27be59e#;
pragma Export (C, u00054, "system__val_lluB");
u00055 : constant Version_32 := 16#fa8db733#;
pragma Export (C, u00055, "system__val_lluS");
u00056 : constant Version_32 := 16#27b600b2#;
pragma Export (C, u00056, "system__val_utilB");
u00057 : constant Version_32 := 16#b187f27f#;
pragma Export (C, u00057, "system__val_utilS");
u00058 : constant Version_32 := 16#d1060688#;
pragma Export (C, u00058, "system__case_utilB");
u00059 : constant Version_32 := 16#392e2d56#;
pragma Export (C, u00059, "system__case_utilS");
u00060 : constant Version_32 := 16#84a27f0d#;
pragma Export (C, u00060, "interfaces__c_streamsB");
u00061 : constant Version_32 := 16#8bb5f2c0#;
pragma Export (C, u00061, "interfaces__c_streamsS");
u00062 : constant Version_32 := 16#6db6928f#;
pragma Export (C, u00062, "system__crtlS");
u00063 : constant Version_32 := 16#4e6a342b#;
pragma Export (C, u00063, "system__file_ioB");
u00064 : constant Version_32 := 16#ba56a5e4#;
pragma Export (C, u00064, "system__file_ioS");
u00065 : constant Version_32 := 16#b7ab275c#;
pragma Export (C, u00065, "ada__finalizationB");
u00066 : constant Version_32 := 16#19f764ca#;
pragma Export (C, u00066, "ada__finalizationS");
u00067 : constant Version_32 := 16#95817ed8#;
pragma Export (C, u00067, "system__finalization_rootB");
u00068 : constant Version_32 := 16#52d53711#;
pragma Export (C, u00068, "system__finalization_rootS");
u00069 : constant Version_32 := 16#769e25e6#;
pragma Export (C, u00069, "interfaces__cB");
u00070 : constant Version_32 := 16#4a38bedb#;
pragma Export (C, u00070, "interfaces__cS");
u00071 : constant Version_32 := 16#07e6ee66#;
pragma Export (C, u00071, "system__os_libB");
u00072 : constant Version_32 := 16#d7b69782#;
pragma Export (C, u00072, "system__os_libS");
u00073 : constant Version_32 := 16#1a817b8e#;
pragma Export (C, u00073, "system__stringsB");
u00074 : constant Version_32 := 16#639855e7#;
pragma Export (C, u00074, "system__stringsS");
u00075 : constant Version_32 := 16#e0b8de29#;
pragma Export (C, u00075, "system__file_control_blockS");
u00076 : constant Version_32 := 16#b5b2aca1#;
pragma Export (C, u00076, "system__finalization_mastersB");
u00077 : constant Version_32 := 16#69316dc1#;
pragma Export (C, u00077, "system__finalization_mastersS");
u00078 : constant Version_32 := 16#57a37a42#;
pragma Export (C, u00078, "system__address_imageB");
u00079 : constant Version_32 := 16#bccbd9bb#;
pragma Export (C, u00079, "system__address_imageS");
u00080 : constant Version_32 := 16#7268f812#;
pragma Export (C, u00080, "system__img_boolB");
u00081 : constant Version_32 := 16#e8fe356a#;
pragma Export (C, u00081, "system__img_boolS");
u00082 : constant Version_32 := 16#d7aac20c#;
pragma Export (C, u00082, "system__ioB");
u00083 : constant Version_32 := 16#8365b3ce#;
pragma Export (C, u00083, "system__ioS");
u00084 : constant Version_32 := 16#6d4d969a#;
pragma Export (C, u00084, "system__storage_poolsB");
u00085 : constant Version_32 := 16#e87cc305#;
pragma Export (C, u00085, "system__storage_poolsS");
u00086 : constant Version_32 := 16#e34550ca#;
pragma Export (C, u00086, "system__pool_globalB");
u00087 : constant Version_32 := 16#c88d2d16#;
pragma Export (C, u00087, "system__pool_globalS");
u00088 : constant Version_32 := 16#9d39c675#;
pragma Export (C, u00088, "system__memoryB");
u00089 : constant Version_32 := 16#445a22b5#;
pragma Export (C, u00089, "system__memoryS");
u00090 : constant Version_32 := 16#6a859064#;
pragma Export (C, u00090, "system__storage_pools__subpoolsB");
u00091 : constant Version_32 := 16#e3b008dc#;
pragma Export (C, u00091, "system__storage_pools__subpoolsS");
u00092 : constant Version_32 := 16#63f11652#;
pragma Export (C, u00092, "system__storage_pools__subpools__finalizationB");
u00093 : constant Version_32 := 16#fe2f4b3a#;
pragma Export (C, u00093, "system__storage_pools__subpools__finalizationS");
-- BEGIN ELABORATION ORDER
-- ada%s
-- interfaces%s
-- system%s
-- system.case_util%s
-- system.case_util%b
-- system.htable%s
-- system.img_bool%s
-- system.img_bool%b
-- system.img_int%s
-- system.img_int%b
-- system.io%s
-- system.io%b
-- system.parameters%s
-- system.parameters%b
-- system.crtl%s
-- interfaces.c_streams%s
-- interfaces.c_streams%b
-- system.standard_library%s
-- system.exceptions_debug%s
-- system.exceptions_debug%b
-- system.storage_elements%s
-- system.storage_elements%b
-- system.stack_checking%s
-- system.stack_checking%b
-- system.string_hash%s
-- system.string_hash%b
-- system.htable%b
-- system.strings%s
-- system.strings%b
-- system.os_lib%s
-- system.traceback_entries%s
-- system.traceback_entries%b
-- ada.exceptions%s
-- system.soft_links%s
-- system.unsigned_types%s
-- system.val_llu%s
-- system.val_util%s
-- system.val_util%b
-- system.val_llu%b
-- system.wch_con%s
-- system.wch_con%b
-- system.wch_cnv%s
-- system.wch_jis%s
-- system.wch_jis%b
-- system.wch_cnv%b
-- system.wch_stw%s
-- system.wch_stw%b
-- ada.exceptions.last_chance_handler%s
-- ada.exceptions.last_chance_handler%b
-- system.address_image%s
-- system.exception_table%s
-- system.exception_table%b
-- ada.io_exceptions%s
-- ada.tags%s
-- ada.streams%s
-- ada.streams%b
-- interfaces.c%s
-- system.exceptions%s
-- system.exceptions%b
-- system.exceptions.machine%s
-- system.finalization_root%s
-- system.finalization_root%b
-- ada.finalization%s
-- ada.finalization%b
-- system.storage_pools%s
-- system.storage_pools%b
-- system.finalization_masters%s
-- system.storage_pools.subpools%s
-- system.storage_pools.subpools.finalization%s
-- system.storage_pools.subpools.finalization%b
-- system.memory%s
-- system.memory%b
-- system.standard_library%b
-- system.pool_global%s
-- system.pool_global%b
-- system.file_control_block%s
-- system.file_io%s
-- system.secondary_stack%s
-- system.file_io%b
-- system.storage_pools.subpools%b
-- system.finalization_masters%b
-- interfaces.c%b
-- ada.tags%b
-- system.soft_links%b
-- system.os_lib%b
-- system.secondary_stack%b
-- system.address_image%b
-- system.traceback%s
-- ada.exceptions%b
-- system.traceback%b
-- ada.text_io%s
-- ada.text_io%b
-- hello%b
-- END ELABORATION ORDER
end ada_main;
.. code-block:: ada
pragma Ada_95;
-- The following source file name pragmas allow the generated file
-- names to be unique for different main programs. They are needed
-- since the package name will always be Ada_Main.
pragma Source_File_Name (ada_main, Spec_File_Name => "b~hello.ads");
pragma Source_File_Name (ada_main, Body_File_Name => "b~hello.adb");
pragma Suppress (Overflow_Check);
with Ada.Exceptions;
-- Generated package body for Ada_Main starts here
package body ada_main is
pragma Warnings (Off);
-- These values are reference counter associated to units which have
-- been elaborated. It is also used to avoid elaborating the
-- same unit twice.
E72 : Short_Integer; pragma Import (Ada, E72, "system__os_lib_E");
E13 : Short_Integer; pragma Import (Ada, E13, "system__soft_links_E");
E23 : Short_Integer; pragma Import (Ada, E23, "system__exception_table_E");
E46 : Short_Integer; pragma Import (Ada, E46, "ada__io_exceptions_E");
E48 : Short_Integer; pragma Import (Ada, E48, "ada__tags_E");
E45 : Short_Integer; pragma Import (Ada, E45, "ada__streams_E");
E70 : Short_Integer; pragma Import (Ada, E70, "interfaces__c_E");
E25 : Short_Integer; pragma Import (Ada, E25, "system__exceptions_E");
E68 : Short_Integer; pragma Import (Ada, E68, "system__finalization_root_E");
E66 : Short_Integer; pragma Import (Ada, E66, "ada__finalization_E");
E85 : Short_Integer; pragma Import (Ada, E85, "system__storage_pools_E");
E77 : Short_Integer; pragma Import (Ada, E77, "system__finalization_masters_E");
E91 : Short_Integer; pragma Import (Ada, E91, "system__storage_pools__subpools_E");
E87 : Short_Integer; pragma Import (Ada, E87, "system__pool_global_E");
E75 : Short_Integer; pragma Import (Ada, E75, "system__file_control_block_E");
E64 : Short_Integer; pragma Import (Ada, E64, "system__file_io_E");
E17 : Short_Integer; pragma Import (Ada, E17, "system__secondary_stack_E");
E06 : Short_Integer; pragma Import (Ada, E06, "ada__text_io_E");
Local_Priority_Specific_Dispatching : constant String := "";
Local_Interrupt_States : constant String := "";
Is_Elaborated : Boolean := False;
procedure finalize_library is
begin
E06 := E06 - 1;
declare
procedure F1;
pragma Import (Ada, F1, "ada__text_io__finalize_spec");
begin
F1;
end;
E77 := E77 - 1;
E91 := E91 - 1;
declare
procedure F2;
pragma Import (Ada, F2, "system__file_io__finalize_body");
begin
E64 := E64 - 1;
F2;
end;
declare
procedure F3;
pragma Import (Ada, F3, "system__file_control_block__finalize_spec");
begin
E75 := E75 - 1;
F3;
end;
E87 := E87 - 1;
declare
procedure F4;
pragma Import (Ada, F4, "system__pool_global__finalize_spec");
begin
F4;
end;
declare
procedure F5;
pragma Import (Ada, F5, "system__storage_pools__subpools__finalize_spec");
begin
F5;
end;
declare
procedure F6;
pragma Import (Ada, F6, "system__finalization_masters__finalize_spec");
begin
F6;
end;
declare
procedure Reraise_Library_Exception_If_Any;
pragma Import (Ada, Reraise_Library_Exception_If_Any, "__gnat_reraise_library_exception_if_any");
begin
Reraise_Library_Exception_If_Any;
end;
end finalize_library;
-------------
-- adainit --
-------------
procedure adainit is
Main_Priority : Integer;
pragma Import (C, Main_Priority, "__gl_main_priority");
Time_Slice_Value : Integer;
pragma Import (C, Time_Slice_Value, "__gl_time_slice_val");
WC_Encoding : Character;
pragma Import (C, WC_Encoding, "__gl_wc_encoding");
Locking_Policy : Character;
pragma Import (C, Locking_Policy, "__gl_locking_policy");
Queuing_Policy : Character;
pragma Import (C, Queuing_Policy, "__gl_queuing_policy");
Task_Dispatching_Policy : Character;
pragma Import (C, Task_Dispatching_Policy, "__gl_task_dispatching_policy");
Priority_Specific_Dispatching : System.Address;
pragma Import (C, Priority_Specific_Dispatching, "__gl_priority_specific_dispatching");
Num_Specific_Dispatching : Integer;
pragma Import (C, Num_Specific_Dispatching, "__gl_num_specific_dispatching");
Main_CPU : Integer;
pragma Import (C, Main_CPU, "__gl_main_cpu");
Interrupt_States : System.Address;
pragma Import (C, Interrupt_States, "__gl_interrupt_states");
Num_Interrupt_States : Integer;
pragma Import (C, Num_Interrupt_States, "__gl_num_interrupt_states");
Unreserve_All_Interrupts : Integer;
pragma Import (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
Detect_Blocking : Integer;
pragma Import (C, Detect_Blocking, "__gl_detect_blocking");
Default_Stack_Size : Integer;
pragma Import (C, Default_Stack_Size, "__gl_default_stack_size");
Leap_Seconds_Support : Integer;
pragma Import (C, Leap_Seconds_Support, "__gl_leap_seconds_support");
procedure Runtime_Initialize;
pragma Import (C, Runtime_Initialize, "__gnat_runtime_initialize");
Finalize_Library_Objects : No_Param_Proc;
pragma Import (C, Finalize_Library_Objects, "__gnat_finalize_library_objects");
-- Start of processing for adainit
begin
-- Record various information for this partition. The values
-- are derived by the binder from information stored in the ali
-- files by the compiler.
if Is_Elaborated then
return;
end if;
Is_Elaborated := True;
Main_Priority := -1;
Time_Slice_Value := -1;
WC_Encoding := 'b';
Locking_Policy := ' ';
Queuing_Policy := ' ';
Task_Dispatching_Policy := ' ';
Priority_Specific_Dispatching :=
Local_Priority_Specific_Dispatching'Address;
Num_Specific_Dispatching := 0;
Main_CPU := -1;
Interrupt_States := Local_Interrupt_States'Address;
Num_Interrupt_States := 0;
Unreserve_All_Interrupts := 0;
Detect_Blocking := 0;
Default_Stack_Size := -1;
Leap_Seconds_Support := 0;
Runtime_Initialize;
Finalize_Library_Objects := finalize_library'access;
-- Now we have the elaboration calls for all units in the partition.
-- The Elab_Spec and Elab_Body attributes generate references to the
-- implicit elaboration procedures generated by the compiler for
-- each unit that requires elaboration. Increment a counter of
-- reference for each unit.
System.Soft_Links'Elab_Spec;
System.Exception_Table'Elab_Body;
E23 := E23 + 1;
Ada.Io_Exceptions'Elab_Spec;
E46 := E46 + 1;
Ada.Tags'Elab_Spec;
Ada.Streams'Elab_Spec;
E45 := E45 + 1;
Interfaces.C'Elab_Spec;
System.Exceptions'Elab_Spec;
E25 := E25 + 1;
System.Finalization_Root'Elab_Spec;
E68 := E68 + 1;
Ada.Finalization'Elab_Spec;
E66 := E66 + 1;
System.Storage_Pools'Elab_Spec;
E85 := E85 + 1;
System.Finalization_Masters'Elab_Spec;
System.Storage_Pools.Subpools'Elab_Spec;
System.Pool_Global'Elab_Spec;
E87 := E87 + 1;
System.File_Control_Block'Elab_Spec;
E75 := E75 + 1;
System.File_Io'Elab_Body;
E64 := E64 + 1;
E91 := E91 + 1;
System.Finalization_Masters'Elab_Body;
E77 := E77 + 1;
E70 := E70 + 1;
Ada.Tags'Elab_Body;
E48 := E48 + 1;
System.Soft_Links'Elab_Body;
E13 := E13 + 1;
System.Os_Lib'Elab_Body;
E72 := E72 + 1;
System.Secondary_Stack'Elab_Body;
E17 := E17 + 1;
Ada.Text_Io'Elab_Spec;
Ada.Text_Io'Elab_Body;
E06 := E06 + 1;
end adainit;
--------------
-- adafinal --
--------------
procedure adafinal is
procedure s_stalib_adafinal;
pragma Import (C, s_stalib_adafinal, "system__standard_library__adafinal");
procedure Runtime_Finalize;
pragma Import (C, Runtime_Finalize, "__gnat_runtime_finalize");
begin
if not Is_Elaborated then
return;
end if;
Is_Elaborated := False;
Runtime_Finalize;
s_stalib_adafinal;
end adafinal;
-- We get to the main program of the partition by using
-- pragma Import because if we try to with the unit and
-- call it Ada style, then not only do we waste time
-- recompiling it, but also, we don't really know the right
-- switches (e.g.@: identifier character set) to be used
-- to compile it.
procedure Ada_Main_Program;
pragma Import (Ada, Ada_Main_Program, "_ada_hello");
----------
-- main --
----------
-- main is actually a function, as in the ANSI C standard,
-- defined to return the exit status. The three parameters
-- are the argument count, argument values and environment
-- pointer.
function main
(argc : Integer;
argv : System.Address;
envp : System.Address)
return Integer
is
-- The initialize routine performs low level system
-- initialization using a standard library routine which
-- sets up signal handling and performs any other
-- required setup. The routine can be found in file
-- a-init.c.
procedure initialize;
pragma Import (C, initialize, "__gnat_initialize");
-- The finalize routine performs low level system
-- finalization using a standard library routine. The
-- routine is found in file a-final.c and in the standard
-- distribution is a dummy routine that does nothing, so
-- really this is a hook for special user finalization.
procedure finalize;
pragma Import (C, finalize, "__gnat_finalize");
-- The following is to initialize the SEH exceptions
SEH : aliased array (1 .. 2) of Integer;
Ensure_Reference : aliased System.Address := Ada_Main_Program_Name'Address;
pragma Volatile (Ensure_Reference);
-- Start of processing for main
begin
-- Save global variables
gnat_argc := argc;
gnat_argv := argv;
gnat_envp := envp;
-- Call low level system initialization
Initialize (SEH'Address);
-- Call our generated Ada initialization routine
adainit;
-- Now we call the main program of the partition
Ada_Main_Program;
-- Perform Ada finalization
adafinal;
-- Perform low level system finalization
Finalize;
-- Return the proper exit status
return (gnat_exit_status);
end;
-- This section is entirely comments, so it has no effect on the
-- compilation of the Ada_Main package. It provides the list of
-- object files and linker options, as well as some standard
-- libraries needed for the link. The gnatlink utility parses
-- this b~hello.adb file to read these comment lines to generate
-- the appropriate command line arguments for the call to the
-- system linker. The BEGIN/END lines are used for sentinels for
-- this parsing operation.
-- The exact file names will of course depend on the environment,
-- host/target and location of files on the host system.
-- BEGIN Object file/option list
-- ./hello.o
-- -L./
-- -L/usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/
-- /usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/libgnat.a
-- END Object file/option list
end ada_main;
The Ada code in the above example is exactly what is generated by the
binder. We have added comments to more clearly indicate the function
of each part of the generated `Ada_Main` package.
The code is standard Ada in all respects, and can be processed by any
tools that handle Ada. In particular, it is possible to use the debugger
in Ada mode to debug the generated `Ada_Main` package. For example,
suppose that for reasons that you do not understand, your program is crashing
during elaboration of the body of `Ada.Text_IO`. To locate this bug,
you can place a breakpoint on the call:
.. code-block:: ada
Ada.Text_Io'Elab_Body;
and trace the elaboration routine for this package to find out where
the problem might be (more usually of course you would be debugging
elaboration code in your own application).
.. _Getting_Started_with_GNAT:
*************************
Getting Started with GNAT
*************************
This chapter describes how to use GNAT's command line interface to build
executable Ada programs.
On most platforms a visually oriented Integrated Development Environment
is also available, the GNAT Programming Studio (GPS).
GPS offers a graphical "look and feel", support for development in
other programming languages, comprehensive browsing features, and
many other capabilities.
For information on GPS please refer to
:title:`Using the GNAT Programming Studio`.
.. _Running_GNAT:
Running GNAT
============
Three steps are needed to create an executable file from an Ada source
file:
* The source file(s) must be compiled.
* The file(s) must be bound using the GNAT binder.
* All appropriate object files must be linked to produce an executable.
All three steps are most commonly handled by using the *gnatmake*
utility program that, given the name of the main program, automatically
performs the necessary compilation, binding and linking steps.
.. _Running_a_Simple_Ada_Program:
Running a Simple Ada Program
============================
Any text editor may be used to prepare an Ada program.
(If Emacs is used, the optional Ada mode may be helpful in laying out the
program.)
The program text is a normal text file. We will assume in our initial
example that you have used your editor to prepare the following
standard format text file:
.. code-block:: ada
with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
begin
Put_Line ("Hello WORLD!");
end Hello;
This file should be named :file:`hello.adb`.
With the normal default file naming conventions, GNAT requires
that each file
contain a single compilation unit whose file name is the
unit name,
with periods replaced by hyphens; the
extension is :file:`ads` for a
spec and :file:`adb` for a body.
You can override this default file naming convention by use of the
special pragma `Source_File_Name` (for further information please
see :ref:`Using_Other_File_Names`).
Alternatively, if you want to rename your files according to this default
convention, which is probably more convenient if you will be using GNAT
for all your compilations, then the `gnatchop` utility
can be used to generate correctly-named source files
(see :ref:`Renaming_Files_with_gnatchop`).
You can compile the program using the following command (`$` is used
as the command prompt in the examples in this document):
.. code-block:: sh
$ gcc -c hello.adb
*gcc* is the command used to run the compiler. This compiler is
capable of compiling programs in several languages, including Ada and
C. It assumes that you have given it an Ada program if the file extension is
either :file:`.ads` or :file:`.adb`, and it will then call
the GNAT compiler to compile the specified file.
The :option:`-c` switch is required. It tells *gcc* to only do a
compilation. (For C programs, *gcc* can also do linking, but this
capability is not used directly for Ada programs, so the :option:`-c`
switch must always be present.)
This compile command generates a file
:file:`hello.o`, which is the object
file corresponding to your Ada program. It also generates
an 'Ada Library Information' file :file:`hello.ali`,
which contains additional information used to check
that an Ada program is consistent.
To build an executable file,
use `gnatbind` to bind the program
and *gnatlink* to link it. The
argument to both `gnatbind` and *gnatlink* is the name of the
:file:`ALI` file, but the default extension of :file:`.ali` can
be omitted. This means that in the most common case, the argument
is simply the name of the main program:
.. code-block:: sh
$ gnatbind hello
$ gnatlink hello
A simpler method of carrying out these steps is to use *gnatmake*,
a master program that invokes all the required
compilation, binding and linking tools in the correct order. In particular,
*gnatmake* automatically recompiles any sources that have been
modified since they were last compiled, or sources that depend
on such modified sources, so that 'version skew' is avoided.
.. index:: Version skew (avoided by *gnatmake*)
.. code-block:: sh
$ gnatmake hello.adb
The result is an executable program called :file:`hello`, which can be
run by entering:
.. code-block:: sh
$ hello
assuming that the current directory is on the search path
for executable programs.
and, if all has gone well, you will see::
Hello WORLD!
appear in response to this command.
.. _Running_a_Program_with_Multiple_Units:
Running a Program with Multiple Units
=====================================
Consider a slightly more complicated example that has three files: a
main program, and the spec and body of a package:
.. code-block:: ada
package Greetings is
procedure Hello;
procedure Goodbye;
end Greetings;
with Ada.Text_IO; use Ada.Text_IO;
package body Greetings is
procedure Hello is
begin
Put_Line ("Hello WORLD!");
end Hello;
procedure Goodbye is
begin
Put_Line ("Goodbye WORLD!");
end Goodbye;
end Greetings;
with Greetings;
procedure Gmain is
begin
Greetings.Hello;
Greetings.Goodbye;
end Gmain;
Following the one-unit-per-file rule, place this program in the
following three separate files:
*greetings.ads*
spec of package `Greetings`
*greetings.adb*
body of package `Greetings`
*gmain.adb*
body of main program
To build an executable version of
this program, we could use four separate steps to compile, bind, and link
the program, as follows:
.. code-block:: sh
$ gcc -c gmain.adb
$ gcc -c greetings.adb
$ gnatbind gmain
$ gnatlink gmain
Note that there is no required order of compilation when using GNAT.
In particular it is perfectly fine to compile the main program first.
Also, it is not necessary to compile package specs in the case where
there is an accompanying body; you only need to compile the body. If you want
to submit these files to the compiler for semantic checking and not code
generation, then use the :option:`-gnatc` switch:
.. code-block:: sh
$ gcc -c greetings.ads -gnatc
Although the compilation can be done in separate steps as in the
above example, in practice it is almost always more convenient
to use the *gnatmake* tool. All you need to know in this case
is the name of the main program's source file. The effect of the above four
commands can be achieved with a single one:
.. code-block:: sh
$ gnatmake gmain.adb
In the next section we discuss the advantages of using *gnatmake* in
more detail.
.. _Using_the_gnatmake_Utility:
Using the *gnatmake* Utility
============================
If you work on a program by compiling single components at a time using
*gcc*, you typically keep track of the units you modify. In order to
build a consistent system, you compile not only these units, but also any
units that depend on the units you have modified.
For example, in the preceding case,
if you edit :file:`gmain.adb`, you only need to recompile that file. But if
you edit :file:`greetings.ads`, you must recompile both
:file:`greetings.adb` and :file:`gmain.adb`, because both files contain
units that depend on :file:`greetings.ads`.
*gnatbind* will warn you if you forget one of these compilation
steps, so that it is impossible to generate an inconsistent program as a
result of forgetting to do a compilation. Nevertheless it is tedious and
error-prone to keep track of dependencies among units.
One approach to handle the dependency-bookkeeping is to use a
makefile. However, makefiles present maintenance problems of their own:
if the dependencies change as you change the program, you must make
sure that the makefile is kept up-to-date manually, which is also an
error-prone process.
The *gnatmake* utility takes care of these details automatically.
Invoke it using either one of the following forms:
.. code-block:: sh
$ gnatmake gmain.adb
$ gnatmake gmain
The argument is the name of the file containing the main program;
you may omit the extension. *gnatmake*
examines the environment, automatically recompiles any files that need
recompiling, and binds and links the resulting set of object files,
generating the executable file, :file:`gmain`.
In a large program, it
can be extremely helpful to use *gnatmake*, because working out by hand
what needs to be recompiled can be difficult.
Note that *gnatmake* takes into account all the Ada rules that
establish dependencies among units. These include dependencies that result
from inlining subprogram bodies, and from
generic instantiation. Unlike some other
Ada make tools, *gnatmake* does not rely on the dependencies that were
found by the compiler on a previous compilation, which may possibly
be wrong when sources change. *gnatmake* determines the exact set of
dependencies from scratch each time it is run.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
.. _Inline_Assembler:
****************
Inline Assembler
****************
.. index:: Inline Assembler
If you need to write low-level software that interacts directly
with the hardware, Ada provides two ways to incorporate assembly
language code into your program. First, you can import and invoke
external routines written in assembly language, an Ada feature fully
supported by GNAT. However, for small sections of code it may be simpler
or more efficient to include assembly language statements directly
in your Ada source program, using the facilities of the implementation-defined
package `System.Machine_Code`, which incorporates the gcc
Inline Assembler. The Inline Assembler approach offers a number of advantages,
including the following:
* No need to use non-Ada tools
* Consistent interface over different targets
* Automatic usage of the proper calling conventions
* Access to Ada constants and variables
* Definition of intrinsic routines
* Possibility of inlining a subprogram comprising assembler code
* Code optimizer can take Inline Assembler code into account
This appendix presents a series of examples to show you how to use
the Inline Assembler. Although it focuses on the Intel x86,
the general approach applies also to other processors.
It is assumed that you are familiar with Ada
and with assembly language programming.
.. _Basic_Assembler_Syntax:
Basic Assembler Syntax
======================
The assembler used by GNAT and gcc is based not on the Intel assembly
language, but rather on a language that descends from the AT&T Unix
assembler *as* (and which is often referred to as 'AT&T syntax').
The following table summarizes the main features of *as* syntax
and points out the differences from the Intel conventions.
See the gcc *as* and *gas* (an *as* macro
pre-processor) documentation for further information.
| *Register names*
| gcc / *as*: Prefix with '%'; for example `%eax`
| Intel: No extra punctuation; for example `eax`
| *Immediate operand*
| gcc / *as*: Prefix with '$'; for example `$4`
| Intel: No extra punctuation; for example `4`
| *Address*
| gcc / *as*: Prefix with '$'; for example `$loc`
| Intel: No extra punctuation; for example `loc`
| *Memory contents*
| gcc / *as*: No extra punctuation; for example `loc`
| Intel: Square brackets; for example `[loc]`
| *Register contents*
| gcc / *as*: Parentheses; for example `(%eax)`
| Intel: Square brackets; for example `[eax]`
| *Hexadecimal numbers*
| gcc / *as*: Leading '0x' (C language syntax); for example `0xA0`
| Intel: Trailing 'h'; for example `A0h`
| *Operand size*
| gcc / *as*: Explicit in op code; for example `movw` to move a 16-bit word
| Intel: Implicit, deduced by assembler; for example `mov`
| *Instruction repetition*
| gcc / *as*: Split into two lines; for example
| `rep`
| `stosl`
| Intel: Keep on one line; for example `rep stosl`
| *Order of operands*
| gcc / *as*: Source first; for example `movw $4, %eax`
| Intel: Destination first; for example `mov eax, 4`
.. _A_Simple_Example_of_Inline_Assembler:
A Simple Example of Inline Assembler
====================================
The following example will generate a single assembly language statement,
`nop`, which does nothing. Despite its lack of run-time effect,
the example will be useful in illustrating the basics of
the Inline Assembler facility.
.. code-block:: ada
with System.Machine_Code; use System.Machine_Code;
procedure Nothing is
begin
Asm ("nop");
end Nothing;
`Asm` is a procedure declared in package `System.Machine_Code`;
here it takes one parameter, a *template string* that must be a static
expression and that will form the generated instruction.
`Asm` may be regarded as a compile-time procedure that parses
the template string and additional parameters (none here),
from which it generates a sequence of assembly language instructions.
The examples in this chapter will illustrate several of the forms
for invoking `Asm`; a complete specification of the syntax
is found in the `Machine_Code_Insertions` section of the
:title:`GNAT Reference Manual`.
Under the standard GNAT conventions, the `Nothing` procedure
should be in a file named :file:`nothing.adb`.
You can build the executable in the usual way:
::
$ gnatmake nothing
However, the interesting aspect of this example is not its run-time behavior
but rather the generated assembly code.
To see this output, invoke the compiler as follows:
::
$ gcc -c -S -fomit-frame-pointer -gnatp nothing.adb
where the options are:
* :samp:`-c`
compile only (no bind or link)
* :samp:`-S`
generate assembler listing
* :samp:`-fomit-frame-pointer`
do not set up separate stack frames
* :samp:`-gnatp`
do not add runtime checks
This gives a human-readable assembler version of the code. The resulting
file will have the same name as the Ada source file, but with a `.s`
extension. In our example, the file :file:`nothing.s` has the following
contents:
::
.file "nothing.adb"
gcc2_compiled.:
___gnu_compiled_ada:
.text
.align 4
.globl __ada_nothing
__ada_nothing:
#APP
nop
#NO_APP
jmp L1
.align 2,0x90
L1:
ret
The assembly code you included is clearly indicated by
the compiler, between the `#APP` and `#NO_APP`
delimiters. The character before the 'APP' and 'NOAPP'
can differ on different targets. For example, GNU/Linux uses '#APP' while
on NT you will see '/APP'.
If you make a mistake in your assembler code (such as using the
wrong size modifier, or using a wrong operand for the instruction) GNAT
will report this error in a temporary file, which will be deleted when
the compilation is finished. Generating an assembler file will help
in such cases, since you can assemble this file separately using the
*as* assembler that comes with gcc.
Assembling the file using the command
::
$ as nothing.s
will give you error messages whose lines correspond to the assembler
input file, so you can easily find and correct any mistakes you made.
If there are no errors, *as* will generate an object file
:file:`nothing.out`.
.. _Output_Variables_in_Inline_Assembler:
Output Variables in Inline Assembler
====================================
The examples in this section, showing how to access the processor flags,
illustrate how to specify the destination operands for assembly language
statements.
.. code-block:: ada
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with System.Machine_Code; use System.Machine_Code;
procedure Get_Flags is
Flags : Unsigned_32;
use ASCII;
begin
Asm ("pushfl" & LF & HT & -- push flags on stack
"popl %%eax" & LF & HT & -- load eax with flags
"movl %%eax, %0", -- store flags in variable
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
Put_Line ("Flags register:" & Flags'Img);
end Get_Flags;
In order to have a nicely aligned assembly listing, we have separated
multiple assembler statements in the Asm template string with linefeed
(ASCII.LF) and horizontal tab (ASCII.HT) characters.
The resulting section of the assembly output file is:
::
#APP
pushfl
popl %eax
movl %eax, -40(%ebp)
#NO_APP
It would have been legal to write the Asm invocation as:
.. code-block:: ada
Asm ("pushfl popl %%eax movl %%eax, %0")
but in the generated assembler file, this would come out as:
::
#APP
pushfl popl %eax movl %eax, -40(%ebp)
#NO_APP
which is not so convenient for the human reader.
We use Ada comments
at the end of each line to explain what the assembler instructions
actually do. This is a useful convention.
When writing Inline Assembler instructions, you need to precede each register
and variable name with a percent sign. Since the assembler already requires
a percent sign at the beginning of a register name, you need two consecutive
percent signs for such names in the Asm template string, thus `%%eax`.
In the generated assembly code, one of the percent signs will be stripped off.
Names such as `%0`, `%1`, `%2`, etc., denote input or output
variables: operands you later define using `Input` or `Output`
parameters to `Asm`.
An output variable is illustrated in
the third statement in the Asm template string:
::
movl %%eax, %0
The intent is to store the contents of the eax register in a variable that can
be accessed in Ada. Simply writing `movl %%eax, Flags` would not
necessarily work, since the compiler might optimize by using a register
to hold Flags, and the expansion of the `movl` instruction would not be
aware of this optimization. The solution is not to store the result directly
but rather to advise the compiler to choose the correct operand form;
that is the purpose of the `%0` output variable.
Information about the output variable is supplied in the `Outputs`
parameter to `Asm`:
.. code-block:: ada
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
The output is defined by the `Asm_Output` attribute of the target type;
the general format is
.. code-block:: ada
Type'Asm_Output (constraint_string, variable_name)
The constraint string directs the compiler how
to store/access the associated variable. In the example
.. code-block:: ada
Unsigned_32'Asm_Output ("=m", Flags);
the `"m"` (memory) constraint tells the compiler that the variable
`Flags` should be stored in a memory variable, thus preventing
the optimizer from keeping it in a register. In contrast,
.. code-block:: ada
Unsigned_32'Asm_Output ("=r", Flags);
uses the `"r"` (register) constraint, telling the compiler to
store the variable in a register.
If the constraint is preceded by the equal character '=', it tells
the compiler that the variable will be used to store data into it.
In the `Get_Flags` example, we used the `"g"` (global) constraint,
allowing the optimizer to choose whatever it deems best.
There are a fairly large number of constraints, but the ones that are
most useful (for the Intel x86 processor) are the following:
====== ==========================================
*=* output constraint
*g* global (i.e., can be stored anywhere)
*m* in memory
*I* a constant
*a* use eax
*b* use ebx
*c* use ecx
*d* use edx
*S* use esi
*D* use edi
*r* use one of eax, ebx, ecx or edx
*q* use one of eax, ebx, ecx, edx, esi or edi
====== ==========================================
The full set of constraints is described in the gcc and *as*
documentation; note that it is possible to combine certain constraints
in one constraint string.
You specify the association of an output variable with an assembler operand
through the :samp:`%{n}` notation, where *n* is a non-negative
integer. Thus in
.. code-block:: ada
Asm ("pushfl" & LF & HT & -- push flags on stack
"popl %%eax" & LF & HT & -- load eax with flags
"movl %%eax, %0", -- store flags in variable
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
`%0` will be replaced in the expanded code by the appropriate operand,
whatever
the compiler decided for the `Flags` variable.
In general, you may have any number of output variables:
* Count the operands starting at 0; thus `%0`, `%1`, etc.
* Specify the `Outputs` parameter as a parenthesized comma-separated list
of `Asm_Output` attributes
For example:
.. code-block:: ada
Asm ("movl %%eax, %0" & LF & HT &
"movl %%ebx, %1" & LF & HT &
"movl %%ecx, %2",
Outputs => (Unsigned_32'Asm_Output ("=g", Var_A), -- %0 = Var_A
Unsigned_32'Asm_Output ("=g", Var_B), -- %1 = Var_B
Unsigned_32'Asm_Output ("=g", Var_C))); -- %2 = Var_C
where `Var_A`, `Var_B`, and `Var_C` are variables
in the Ada program.
As a variation on the `Get_Flags` example, we can use the constraints
string to direct the compiler to store the eax register into the `Flags`
variable, instead of including the store instruction explicitly in the
`Asm` template string:
.. code-block:: ada
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with System.Machine_Code; use System.Machine_Code;
procedure Get_Flags_2 is
Flags : Unsigned_32;
use ASCII;
begin
Asm ("pushfl" & LF & HT & -- push flags on stack
"popl %%eax", -- save flags in eax
Outputs => Unsigned_32'Asm_Output ("=a", Flags));
Put_Line ("Flags register:" & Flags'Img);
end Get_Flags_2;
The `"a"` constraint tells the compiler that the `Flags`
variable will come from the eax register. Here is the resulting code:
::
#APP
pushfl
popl %eax
#NO_APP
movl %eax,-40(%ebp)
The compiler generated the store of eax into Flags after
expanding the assembler code.
Actually, there was no need to pop the flags into the eax register;
more simply, we could just pop the flags directly into the program variable:
.. code-block:: ada
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with System.Machine_Code; use System.Machine_Code;
procedure Get_Flags_3 is
Flags : Unsigned_32;
use ASCII;
begin
Asm ("pushfl" & LF & HT & -- push flags on stack
"pop %0", -- save flags in Flags
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
Put_Line ("Flags register:" & Flags'Img);
end Get_Flags_3;
.. _Input_Variables_in_Inline_Assembler:
Input Variables in Inline Assembler
===================================
The example in this section illustrates how to specify the source operands
for assembly language statements.
The program simply increments its input value by 1:
.. code-block:: ada
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with System.Machine_Code; use System.Machine_Code;
procedure Increment is
function Incr (Value : Unsigned_32) return Unsigned_32 is
Result : Unsigned_32;
begin
Asm ("incl %0",
Outputs => Unsigned_32'Asm_Output ("=a", Result),
Inputs => Unsigned_32'Asm_Input ("a", Value));
return Result;
end Incr;
Value : Unsigned_32;
begin
Value := 5;
Put_Line ("Value before is" & Value'Img);
Value := Incr (Value);
Put_Line ("Value after is" & Value'Img);
end Increment;
The `Outputs` parameter to `Asm` specifies
that the result will be in the eax register and that it is to be stored
in the `Result` variable.
The `Inputs` parameter looks much like the `Outputs` parameter,
but with an `Asm_Input` attribute.
The `"="` constraint, indicating an output value, is not present.
You can have multiple input variables, in the same way that you can have more
than one output variable.
The parameter count (%0, %1) etc, still starts at the first output statement,
and continues with the input statements.
Just as the `Outputs` parameter causes the register to be stored into the
target variable after execution of the assembler statements, so does the
`Inputs` parameter cause its variable to be loaded into the register
before execution of the assembler statements.
Thus the effect of the `Asm` invocation is:
* load the 32-bit value of `Value` into eax
* execute the `incl %eax` instruction
* store the contents of eax into the `Result` variable
The resulting assembler file (with *-O2* optimization) contains:
::
_increment__incr.1:
subl $4,%esp
movl 8(%esp),%eax
#APP
incl %eax
#NO_APP
movl %eax,%edx
movl %ecx,(%esp)
addl $4,%esp
ret
.. _Inlining_Inline_Assembler_Code:
Inlining Inline Assembler Code
==============================
For a short subprogram such as the `Incr` function in the previous
section, the overhead of the call and return (creating / deleting the stack
frame) can be significant, compared to the amount of code in the subprogram
body. A solution is to apply Ada's `Inline` pragma to the subprogram,
which directs the compiler to expand invocations of the subprogram at the
point(s) of call, instead of setting up a stack frame for out-of-line calls.
Here is the resulting program:
.. code-block:: ada
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with System.Machine_Code; use System.Machine_Code;
procedure Increment_2 is
function Incr (Value : Unsigned_32) return Unsigned_32 is
Result : Unsigned_32;
begin
Asm ("incl %0",
Outputs => Unsigned_32'Asm_Output ("=a", Result),
Inputs => Unsigned_32'Asm_Input ("a", Value));
return Result;
end Incr;
pragma Inline (Increment);
Value : Unsigned_32;
begin
Value := 5;
Put_Line ("Value before is" & Value'Img);
Value := Increment (Value);
Put_Line ("Value after is" & Value'Img);
end Increment_2;
Compile the program with both optimization (*-O2*) and inlining
(*-gnatn*) enabled.
The `Incr` function is still compiled as usual, but at the
point in `Increment` where our function used to be called:
::
pushl %edi
call _increment__incr.1
the code for the function body directly appears:
::
movl %esi,%eax
#APP
incl %eax
#NO_APP
movl %eax,%edx
thus saving the overhead of stack frame setup and an out-of-line call.
.. _Other_`Asm`_Functionality:
Other `Asm` Functionality
=========================
This section describes two important parameters to the `Asm`
procedure: `Clobber`, which identifies register usage;
and `Volatile`, which inhibits unwanted optimizations.
.. _The_`Clobber`_Parameter:
The `Clobber` Parameter
-----------------------
One of the dangers of intermixing assembly language and a compiled language
such as Ada is that the compiler needs to be aware of which registers are
being used by the assembly code. In some cases, such as the earlier examples,
the constraint string is sufficient to indicate register usage (e.g.,
`"a"` for
the eax register). But more generally, the compiler needs an explicit
identification of the registers that are used by the Inline Assembly
statements.
Using a register that the compiler doesn't know about
could be a side effect of an instruction (like `mull`
storing its result in both eax and edx).
It can also arise from explicit register usage in your
assembly code; for example:
.. code-block:: ada
Asm ("movl %0, %%ebx" & LF & HT &
"movl %%ebx, %1",
Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
Inputs => Unsigned_32'Asm_Input ("g", Var_In));
where the compiler (since it does not analyze the `Asm` template string)
does not know you are using the ebx register.
In such cases you need to supply the `Clobber` parameter to `Asm`,
to identify the registers that will be used by your assembly code:
.. code-block:: ada
Asm ("movl %0, %%ebx" & LF & HT &
"movl %%ebx, %1",
Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
Inputs => Unsigned_32'Asm_Input ("g", Var_In),
Clobber => "ebx");
The Clobber parameter is a static string expression specifying the
register(s) you are using. Note that register names are *not* prefixed
by a percent sign. Also, if more than one register is used then their names
are separated by commas; e.g., `"eax, ebx"`
The `Clobber` parameter has several additional uses:
* Use 'register' name `cc` to indicate that flags might have changed
* Use 'register' name `memory` if you changed a memory location
.. _The_`Volatile`_Parameter:
The `Volatile` Parameter
------------------------
.. index:: Volatile parameter
Compiler optimizations in the presence of Inline Assembler may sometimes have
unwanted effects. For example, when an `Asm` invocation with an input
variable is inside a loop, the compiler might move the loading of the input
variable outside the loop, regarding it as a one-time initialization.
If this effect is not desired, you can disable such optimizations by setting
the `Volatile` parameter to `True`; for example:
.. code-block:: ada
Asm ("movl %0, %%ebx" & LF & HT &
"movl %%ebx, %1",
Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
Inputs => Unsigned_32'Asm_Input ("g", Var_In),
Clobber => "ebx",
Volatile => True);
By default, `Volatile` is set to `False` unless there is no
`Outputs` parameter.
Although setting `Volatile` to `True` prevents unwanted
optimizations, it will also disable other optimizations that might be
important for efficiency. In general, you should set `Volatile`
to `True` only if the compiler's optimizations have created
problems.
.. -- Non-breaking space in running text
-- E.g. Ada |nbsp| 95
.. |nbsp| unicode:: 0xA0
:trim:
.. _Platform_Specific_Information:
*****************************
Platform-Specific Information
*****************************
This appendix contains information relating to the implementation
of run-time libraries on various platforms and also covers
topics related to the GNAT implementation on Windows and Mac OS.
.. _`Run_Time_Libraries`:
Run-Time Libraries
==================
.. index:: Tasking and threads libraries
.. index:: Threads libraries and tasking
.. index:: Run-time libraries (platform-specific information)
The GNAT run-time implementation may vary with respect to both the
underlying threads library and the exception handling scheme.
For threads support, one or more of the following are supplied:
* **native threads library**, a binding to the thread package from
the underlying operating system
* **pthreads library** (Sparc Solaris only), a binding to the Solaris
POSIX thread package
For exception handling, either or both of two models are supplied:
.. index:: Zero-Cost Exceptions
.. index:: ZCX (Zero-Cost Exceptions)
* **Zero-Cost Exceptions** ("ZCX"),
which uses binder-generated tables that
are interrogated at run time to locate a handler.
.. index:: setjmp/longjmp Exception Model
.. index:: SJLJ (setjmp/longjmp Exception Model)
* **setjmp / longjmp** ('SJLJ'),
which uses dynamically-set data to establish
the set of handlers
Most programs should experience a substantial speed improvement by
being compiled with a ZCX run-time.
This is especially true for
tasking applications or applications with many exception handlers.}
This section summarizes which combinations of threads and exception support
are supplied on various GNAT platforms.
It then shows how to select a particular library either
permanently or temporarily,
explains the properties of (and tradeoffs among) the various threads
libraries, and provides some additional
information about several specific platforms.
.. _Summary_of_Run-Time_Configurations:
Summary of Run-Time Configurations
----------------------------------
+-----------------+--------------+-------------------------+------------+
| Platform | Run-Time | Tasking | Exceptions |
+=================+==============+=========================+============+
| ppc-aix | rts-native | native AIX threads | ZCX |
| | (default) | | |
| +--------------+-------------------------+------------+
| | rts-sjlj | native AIX threads | SJLJ |
+-----------------+--------------+-------------------------+------------+
| sparc-solaris | rts-native | native Solaris | ZCX |
| | (default) | threads library | |
| +--------------+-------------------------+------------+
| | rts-pthread | pthread library | ZCX |
| +--------------+-------------------------+------------+
| | rts-sjlj | native Solaris | SJLJ |
| | | threads library | |
+-----------------+--------------+-------------------------+------------+
| sparc64-solaris | rts-native | native Solaris | ZCX |
| | (default) | threads library | |
+-----------------+--------------+-------------------------+------------+
| x86-linux | rts-native | pthread library | ZCX |
| | (default) | | |
| +--------------+-------------------------+------------+
| | rts-sjlj | pthread library | SJLJ |
+-----------------+--------------+-------------------------+------------+
| x86-lynx | rts-native | native LynxOS threads | SJLJ |
| | (default) | | |
+-----------------+--------------+-------------------------+------------+
| x86-solaris | rts-native | native Solaris | ZCX |
| | (default) | threads library | |
| +--------------+-------------------------+------------+
| | rts-sjlj | native Solaris | SJLJ |
| | | threads library | |
+-----------------+--------------+-------------------------+------------+
| x86-windows | rts-native | native Win32 threads | ZCX |
| | (default) | | |
| +--------------+-------------------------+------------+
| | rts-sjlj | native Win32 threads | SJLJ |
+-----------------+--------------+-------------------------+------------+
| x86_64-linux | rts-native | pthread library | ZCX |
| | (default) | | |
| +--------------+-------------------------+------------+
| | rts-sjlj | pthread library | SJLJ |
+-----------------+--------------+-------------------------+------------+
.. _Specifying_a_Run-Time_Library:
Specifying a Run-Time Library
=============================
The :file:`adainclude` subdirectory containing the sources of the GNAT
run-time library, and the :file:`adalib` subdirectory containing the
:file:`ALI` files and the static and/or shared GNAT library, are located
in the gcc target-dependent area:
::
target=$prefix/lib/gcc/gcc-*dumpmachine*/gcc-*dumpversion*/
As indicated above, on some platforms several run-time libraries are supplied.
These libraries are installed in the target dependent area and
contain a complete source and binary subdirectory. The detailed description
below explains the differences between the different libraries in terms of
their thread support.
The default run-time library (when GNAT is installed) is *rts-native*.
This default run time is selected by the means of soft links.
For example on x86-linux:
.. image:: rtlibrary-structure.png
.. --
-- $(target-dir)
-- |
-- +--- adainclude----------+
-- | |
-- +--- adalib-----------+ |
-- | | |
-- +--- rts-native | |
-- | | | |
-- | +--- adainclude <---+
-- | | |
-- | +--- adalib <----+
-- |
-- +--- rts-sjlj
-- |
-- +--- adainclude
-- |
-- +--- adalib
If the *rts-sjlj* library is to be selected on a permanent basis,
these soft links can be modified with the following commands:
::
$ cd $target
$ rm -f adainclude adalib
$ ln -s rts-sjlj/adainclude adainclude
$ ln -s rts-sjlj/adalib adalib
Alternatively, you can specify :file:`rts-sjlj/adainclude` in the file
:file:`$target/ada_source_path` and :file:`rts-sjlj/adalib` in
:file:`$target/ada_object_path`.
.. index:: --RTS option
Selecting another run-time library temporarily can be
achieved by using the *--RTS* switch, e.g., *--RTS=sjlj*
.. _Choosing_the_Scheduling_Policy:
.. index:: SCHED_FIFO scheduling policy
.. index:: SCHED_RR scheduling policy
.. index:: SCHED_OTHER scheduling policy
Choosing the Scheduling Policy
------------------------------
When using a POSIX threads implementation, you have a choice of several
scheduling policies: `SCHED_FIFO`, `SCHED_RR` and `SCHED_OTHER`.
Typically, the default is `SCHED_OTHER`, while using `SCHED_FIFO`
or `SCHED_RR` requires special (e.g., root) privileges.
.. index:: pragma Time_Slice
.. index:: -T0 option
.. index:: pragma Task_Dispatching_Policy
By default, GNAT uses the `SCHED_OTHER` policy. To specify
`SCHED_FIFO`,
you can use one of the following:
* `pragma Time_Slice (0.0)`
* the corresponding binder option *-T0*
* `pragma Task_Dispatching_Policy (FIFO_Within_Priorities)`
To specify `SCHED_RR`,
you should use `pragma Time_Slice` with a
value greater than 0.0, or else use the corresponding *-T*
binder option.
.. index:: Solaris Sparc threads libraries
.. _Solaris-Specific_Considerations:
Solaris-Specific Considerations
-------------------------------
This section addresses some topics related to the various threads libraries
on Sparc Solaris.
.. index:: rts-pthread threads library
.. _Solaris_Threads_Issues:
Solaris Threads Issues
----------------------
GNAT under Solaris/Sparc 32 bits comes with an alternate tasking run-time
library based on POSIX threads --- *rts-pthread*.
.. index:: PTHREAD_PRIO_INHERIT policy (under rts-pthread)
.. index:: PTHREAD_PRIO_PROTECT policy (under rts-pthread)
.. index:: pragma Locking_Policy (under rts-pthread)
.. index:: Inheritance_Locking (under rts-pthread)
.. index:: Ceiling_Locking (under rts-pthread)
This run-time library has the advantage of being mostly shared across all
POSIX-compliant thread implementations, and it also provides under
Solaris |nbsp| 8 the `PTHREAD_PRIO_INHERIT`
and `PTHREAD_PRIO_PROTECT`
semantics that can be selected using the predefined pragma
`Locking_Policy`
with respectively
`Inheritance_Locking` and `Ceiling_Locking` as the policy.
As explained above, the native run-time library is based on the Solaris thread
library (`libthread`) and is the default library.
.. index:: GNAT_PROCESSOR environment variable (on Sparc Solaris)
When the Solaris threads library is used (this is the default), programs
compiled with GNAT can automatically take advantage of
and can thus execute on multiple processors.
The user can alternatively specify a processor on which the program should run
to emulate a single-processor system. The multiprocessor / uniprocessor choice
is made by
setting the environment variable :envvar:`GNAT_PROCESSOR`
to one of the following:
========================= ===================================================================
``GNAT_PROCESSOR`` Value Effect
========================= ===================================================================
*-2* Use the default configuration (run the program on all
available processors) - this is the same as having `GNAT_PROCESSOR`
unset
*-1* Let the run-time implementation choose one processor and run the
program on that processor
*0 .. Last_Proc* Run the program on the specified processor.
`Last_Proc` is equal to `_SC_NPROCESSORS_CONF - 1`
(where `_SC_NPROCESSORS_CONF` is a system variable).
========================= ===================================================================
.. _AIX-Specific_Considerations:
AIX-Specific Considerations
---------------------------
.. index:: AIX resolver library
On AIX, the resolver library initializes some internal structure on
the first call to `get*by*` functions, which are used to implement
`GNAT.Sockets.Get_Host_By_Name` and
`GNAT.Sockets.Get_Host_By_Address`.
If such initialization occurs within an Ada task, and the stack size for
the task is the default size, a stack overflow may occur.
To avoid this overflow, the user should either ensure that the first call
to `GNAT.Sockets.Get_Host_By_Name` or
`GNAT.Sockets.Get_Host_By_Addrss`
occurs in the environment task, or use `pragma Storage_Size` to
specify a sufficiently large size for the stack of the task that contains
this call.
.. index:: Windows NT
.. index:: Windows 95
.. index:: Windows 98
.. _Microsoft_Windows_Topics:
Microsoft Windows Topics
========================
This section describes topics that are specific to the Microsoft Windows
platforms.
.. only:: PRO or GPL
.. rubric:: Installing from the Command Line
By default the GNAT installers display a GUI that prompts you to enter
the installation path and similar information, and then guides you through the
installation process. It is also possible to perform silent installations
using the command-line interface.
In order to install one of the GNAT installers from the command
line you should pass parameter `/S` (and, optionally,
`/D=<directory>`) as command-line arguments.
.. only:: PRO
For example, for an unattended installation of
GNAT 7.0.2 into the default directory
`C:\\GNATPRO\\7.0.2` you would run:
::
gnatpro-7.0.2-i686-pc-mingw32-bin.exe /S
To install into a custom directory, say, `C:\\TOOLS\\GNATPRO\\7.0.2`:
::
gnatpro-7.0.2-i686-pc-mingw32-bin /S /D=C:\TOOLS\GNATPRO\7.0.2
.. only:: GPL
For example, for an unattended installation of
GNAT 2012 into `C:\\GNAT\\2012`:
::
gnat-gpl-2012-i686-pc-mingw32-bin /S /D=C:\GNAT\2012
.. only:: PRO or GPL
You can use the same syntax for all installers.
Note that unattended installations don't modify system path, nor create file
associations, so such activities need to be done by hand.
.. _Using_GNAT_on_Windows:
Using GNAT on Windows
---------------------
One of the strengths of the GNAT technology is that its tool set
(*gcc*, *gnatbind*, *gnatlink*, *gnatmake*, the
`gdb` debugger, etc.) is used in the same way regardless of the
platform.
On Windows this tool set is complemented by a number of Microsoft-specific
tools that have been provided to facilitate interoperability with Windows
when this is required. With these tools:
* You can build applications using the `CONSOLE` or `WINDOWS`
subsystems.
* You can use any Dynamically Linked Library (DLL) in your Ada code (both
relocatable and non-relocatable DLLs are supported).
* You can build Ada DLLs for use in other applications. These applications
can be written in a language other than Ada (e.g., C, C++, etc). Again both
relocatable and non-relocatable Ada DLLs are supported.
* You can include Windows resources in your Ada application.
* You can use or create COM/DCOM objects.
Immediately below are listed all known general GNAT-for-Windows restrictions.
Other restrictions about specific features like Windows Resources and DLLs
are listed in separate sections below.
* It is not possible to use `GetLastError` and `SetLastError`
when tasking, protected records, or exceptions are used. In these
cases, in order to implement Ada semantics, the GNAT run-time system
calls certain Win32 routines that set the last error variable to 0 upon
success. It should be possible to use `GetLastError` and
`SetLastError` when tasking, protected record, and exception
features are not used, but it is not guaranteed to work.
* It is not possible to link against Microsoft C++ libraries except for
import libraries. Interfacing must be done by the mean of DLLs.
* It is possible to link against Microsoft C libraries. Yet the preferred
solution is to use C/C++ compiler that comes with GNAT, since it
doesn't require having two different development environments and makes the
inter-language debugging experience smoother.
* When the compilation environment is located on FAT32 drives, users may
experience recompilations of the source files that have not changed if
Daylight Saving Time (DST) state has changed since the last time files
were compiled. NTFS drives do not have this problem.
* No components of the GNAT toolset use any entries in the Windows
registry. The only entries that can be created are file associations and
PATH settings, provided the user has chosen to create them at installation
time, as well as some minimal book-keeping information needed to correctly
uninstall or integrate different GNAT products.
.. _Using_a_network_installation_of_GNAT:
Using a network installation of GNAT
------------------------------------
Make sure the system on which GNAT is installed is accessible from the
current machine, i.e., the install location is shared over the network.
Shared resources are accessed on Windows by means of UNC paths, which
have the format `\\\\server\\sharename\\path`
In order to use such a network installation, simply add the UNC path of the
:file:`bin` directory of your GNAT installation in front of your PATH. For
example, if GNAT is installed in :file:`\\GNAT` directory of a share location
called :file:`c-drive` on a machine :file:`LOKI`, the following command will
make it available:
::
$ path \\loki\c-drive\gnat\bin;%path%`
Be aware that every compilation using the network installation results in the
transfer of large amounts of data across the network and will likely cause
serious performance penalty.
.. _CONSOLE_and_WINDOWS_subsystems:
CONSOLE and WINDOWS subsystems
------------------------------
.. index:: CONSOLE Subsystem
.. index:: WINDOWS Subsystem
.. index:: -mwindows
There are two main subsystems under Windows. The `CONSOLE` subsystem
(which is the default subsystem) will always create a console when
launching the application. This is not something desirable when the
application has a Windows GUI. To get rid of this console the
application must be using the `WINDOWS` subsystem. To do so
the *-mwindows* linker option must be specified.
::
$ gnatmake winprog -largs -mwindows
.. _Temporary_Files:
Temporary Files
---------------
.. index:: Temporary files
It is possible to control where temporary files gets created by setting
the :envvar:`TMP` environment variable. The file will be created:
* Under the directory pointed to by the :envvar:`TMP` environment variable if
this directory exists.
* Under :file:`c:\\temp`, if the :envvar:`TMP` environment variable is not
set (or not pointing to a directory) and if this directory exists.
* Under the current working directory otherwise.
This allows you to determine exactly where the temporary
file will be created. This is particularly useful in networked
environments where you may not have write access to some
directories.
.. _Mixed-Language_Programming_on_Windows:
Mixed-Language Programming on Windows
-------------------------------------
Developing pure Ada applications on Windows is no different than on
other GNAT-supported platforms. However, when developing or porting an
application that contains a mix of Ada and C/C++, the choice of your
Windows C/C++ development environment conditions your overall
interoperability strategy.
If you use *gcc* or Microsoft C to compile the non-Ada part of
your application, there are no Windows-specific restrictions that
affect the overall interoperability with your Ada code. If you do want
to use the Microsoft tools for your C++ code, you have two choices:
* Encapsulate your C++ code in a DLL to be linked with your Ada
application. In this case, use the Microsoft or whatever environment to
build the DLL and use GNAT to build your executable
(:ref:`Using_DLLs_with_GNAT`).
* Or you can encapsulate your Ada code in a DLL to be linked with the
other part of your application. In this case, use GNAT to build the DLL
(:ref:`Building_DLLs_with_GNAT_Project_files`) and use the Microsoft
or whatever environment to build your executable.
In addition to the description about C main in
:ref:`Mixed_Language_Programming` section, if the C main uses a
stand-alone library it is required on x86-windows to
setup the SEH context. For this the C main must looks like this:
.. code-block:: c
/* main.c */
extern void adainit (void);
extern void adafinal (void);
extern void __gnat_initialize(void*);
extern void call_to_ada (void);
int main (int argc, char *argv[])
{
int SEH [2];
/* Initialize the SEH context */
__gnat_initialize (&SEH);
adainit();
/* Then call Ada services in the stand-alone library */
call_to_ada();
adafinal();
}
Note that this is not needed on x86_64-windows where the Windows
native SEH support is used.
.. _Windows_Calling_Conventions:
Windows Calling Conventions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: Stdcall
.. index:: APIENTRY
This section pertain only to Win32. On Win64 there is a single native
calling convention. All convention specifiers are ignored on this
platform.
When a subprogram `F` (caller) calls a subprogram `G`
(callee), there are several ways to push `G`'s parameters on the
stack and there are several possible scenarios to clean up the stack
upon `G`'s return. A calling convention is an agreed upon software
protocol whereby the responsibilities between the caller (`F`) and
the callee (`G`) are clearly defined. Several calling conventions
are available for Windows:
* `C` (Microsoft defined)
* `Stdcall` (Microsoft defined)
* `Win32` (GNAT specific)
* `DLL` (GNAT specific)
.. _C_Calling_Convention:
`C` Calling Convention
""""""""""""""""""""""
This is the default calling convention used when interfacing to C/C++
routines compiled with either *gcc* or Microsoft Visual C++.
In the `C` calling convention subprogram parameters are pushed on the
stack by the caller from right to left. The caller itself is in charge of
cleaning up the stack after the call. In addition, the name of a routine
with `C` calling convention is mangled by adding a leading underscore.
The name to use on the Ada side when importing (or exporting) a routine
with `C` calling convention is the name of the routine. For
instance the C function:
::
int get_val (long);
should be imported from Ada as follows:
.. code-block:: ada
function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
pragma Import (C, Get_Val, External_Name => "get_val");
Note that in this particular case the `External_Name` parameter could
have been omitted since, when missing, this parameter is taken to be the
name of the Ada entity in lower case. When the `Link_Name` parameter
is missing, as in the above example, this parameter is set to be the
`External_Name` with a leading underscore.
When importing a variable defined in C, you should always use the `C`
calling convention unless the object containing the variable is part of a
DLL (in which case you should use the `Stdcall` calling
convention, :ref:`Stdcall_Calling_Convention`).
.. _Stdcall_Calling_Convention:
`Stdcall` Calling Convention
""""""""""""""""""""""""""""
This convention, which was the calling convention used for Pascal
programs, is used by Microsoft for all the routines in the Win32 API for
efficiency reasons. It must be used to import any routine for which this
convention was specified.
In the `Stdcall` calling convention subprogram parameters are pushed
on the stack by the caller from right to left. The callee (and not the
caller) is in charge of cleaning the stack on routine exit. In addition,
the name of a routine with `Stdcall` calling convention is mangled by
adding a leading underscore (as for the `C` calling convention) and a
trailing :samp:`@{nn}`, where `nn` is the overall size (in
bytes) of the parameters passed to the routine.
The name to use on the Ada side when importing a C routine with a
`Stdcall` calling convention is the name of the C routine. The leading
underscore and trailing :samp:`@{nn}` are added automatically by
the compiler. For instance the Win32 function:
::
APIENTRY int get_val (long);
should be imported from Ada as follows:
.. code-block:: ada
function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
pragma Import (Stdcall, Get_Val);
-- On the x86 a long is 4 bytes, so the Link_Name is "_get_val@4"
As for the `C` calling convention, when the `External_Name`
parameter is missing, it is taken to be the name of the Ada entity in lower
case. If instead of writing the above import pragma you write:
.. code-block:: ada
function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val");
then the imported routine is `_retrieve_val@4`. However, if instead
of specifying the `External_Name` parameter you specify the
`Link_Name` as in the following example:
.. code-block:: ada
function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val");
then the imported routine is `retrieve_val`, that is, there is no
decoration at all. No leading underscore and no Stdcall suffix
:samp:`@{nn}`.
This is especially important as in some special cases a DLL's entry
point name lacks a trailing :samp:`@{nn}` while the exported
name generated for a call has it.
It is also possible to import variables defined in a DLL by using an
import pragma for a variable. As an example, if a DLL contains a
variable defined as:
.. code-block:: c
int my_var;
then, to access this variable from Ada you should write:
.. code-block:: ada
My_Var : Interfaces.C.int;
pragma Import (Stdcall, My_Var);
Note that to ease building cross-platform bindings this convention
will be handled as a `C` calling convention on non-Windows platforms.
.. _Win32_Calling_Convention:
`Win32` Calling Convention
""""""""""""""""""""""""""
This convention, which is GNAT-specific is fully equivalent to the
`Stdcall` calling convention described above.
.. _DLL_Calling_Convention:
`DLL` Calling Convention
""""""""""""""""""""""""
This convention, which is GNAT-specific is fully equivalent to the
`Stdcall` calling convention described above.
.. _Introduction_to_Dynamic_Link_Libraries_DLLs:
Introduction to Dynamic Link Libraries (DLLs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: DLL
A Dynamically Linked Library (DLL) is a library that can be shared by
several applications running under Windows. A DLL can contain any number of
routines and variables.
One advantage of DLLs is that you can change and enhance them without
forcing all the applications that depend on them to be relinked or
recompiled. However, you should be aware than all calls to DLL routines are
slower since, as you will understand below, such calls are indirect.
To illustrate the remainder of this section, suppose that an application
wants to use the services of a DLL :file:`API.dll`. To use the services
provided by :file:`API.dll` you must statically link against the DLL or
an import library which contains a jump table with an entry for each
routine and variable exported by the DLL. In the Microsoft world this
import library is called :file:`API.lib`. When using GNAT this import
library is called either :file:`libAPI.dll.a`, :file:`libapi.dll.a`,
:file:`libAPI.a` or :file:`libapi.a` (names are case insensitive).
After you have linked your application with the DLL or the import library
and you run your application, here is what happens:
* Your application is loaded into memory.
* The DLL :file:`API.dll` is mapped into the address space of your
application. This means that:
- The DLL will use the stack of the calling thread.
- The DLL will use the virtual address space of the calling process.
- The DLL will allocate memory from the virtual address space of the calling
process.
- Handles (pointers) can be safely exchanged between routines in the DLL
routines and routines in the application using the DLL.
* The entries in the jump table (from the import library :file:`libAPI.dll.a`
or :file:`API.lib` or automatically created when linking against a DLL)
which is part of your application are initialized with the addresses
of the routines and variables in :file:`API.dll`.
* If present in :file:`API.dll`, routines `DllMain` or
`DllMainCRTStartup` are invoked. These routines typically contain
the initialization code needed for the well-being of the routines and
variables exported by the DLL.
There is an additional point which is worth mentioning. In the Windows
world there are two kind of DLLs: relocatable and non-relocatable
DLLs. Non-relocatable DLLs can only be loaded at a very specific address
in the target application address space. If the addresses of two
non-relocatable DLLs overlap and these happen to be used by the same
application, a conflict will occur and the application will run
incorrectly. Hence, when possible, it is always preferable to use and
build relocatable DLLs. Both relocatable and non-relocatable DLLs are
supported by GNAT. Note that the *-s* linker option (see GNU Linker
User's Guide) removes the debugging symbols from the DLL but the DLL can
still be relocated.
As a side note, an interesting difference between Microsoft DLLs and
Unix shared libraries, is the fact that on most Unix systems all public
routines are exported by default in a Unix shared library, while under
Windows it is possible (but not required) to list exported routines in
a definition file (see :ref:`The Definition File <The_Definition_File>`).
.. _Using_DLLs_with_GNAT:
Using DLLs with GNAT
^^^^^^^^^^^^^^^^^^^^
To use the services of a DLL, say :file:`API.dll`, in your Ada application
you must have:
* The Ada spec for the routines and/or variables you want to access in
:file:`API.dll`. If not available this Ada spec must be built from the C/C++
header files provided with the DLL.
* The import library (:file:`libAPI.dll.a` or :file:`API.lib`). As previously
mentioned an import library is a statically linked library containing the
import table which will be filled at load time to point to the actual
:file:`API.dll` routines. Sometimes you don't have an import library for the
DLL you want to use. The following sections will explain how to build
one. Note that this is optional.
* The actual DLL, :file:`API.dll`.
Once you have all the above, to compile an Ada application that uses the
services of :file:`API.dll` and whose main subprogram is `My_Ada_App`,
you simply issue the command
::
$ gnatmake my_ada_app -largs -lAPI
The argument *-largs -lAPI* at the end of the *gnatmake* command
tells the GNAT linker to look for an import library. The linker will
look for a library name in this specific order:
* :file:`libAPI.dll.a`
* :file:`API.dll.a`
* :file:`libAPI.a`
* :file:`API.lib`
* :file:`libAPI.dll`
* :file:`API.dll`
The first three are the GNU style import libraries. The third is the
Microsoft style import libraries. The last two are the actual DLL names.
Note that if the Ada package spec for :file:`API.dll` contains the
following pragma
.. code-block:: ada
pragma Linker_Options ("-lAPI");
you do not have to add *-largs -lAPI* at the end of the
*gnatmake* command.
If any one of the items above is missing you will have to create it
yourself. The following sections explain how to do so using as an
example a fictitious DLL called :file:`API.dll`.
.. _Creating_an_Ada_Spec_for_the_DLL_Services:
Creating an Ada Spec for the DLL Services
"""""""""""""""""""""""""""""""""""""""""
A DLL typically comes with a C/C++ header file which provides the
definitions of the routines and variables exported by the DLL. The Ada
equivalent of this header file is a package spec that contains definitions
for the imported entities. If the DLL you intend to use does not come with
an Ada spec you have to generate one such spec yourself. For example if
the header file of :file:`API.dll` is a file :file:`api.h` containing the
following two definitions:
.. code-block:: c
int some_var;
int get (char *);
then the equivalent Ada spec could be:
.. code-block:: ada
with Interfaces.C.Strings;
package API is
use Interfaces;
Some_Var : C.int;
function Get (Str : C.Strings.Chars_Ptr) return C.int;
private
pragma Import (C, Get);
pragma Import (DLL, Some_Var);
end API;
.. _Creating_an_Import_Library:
Creating an Import Library
""""""""""""""""""""""""""
.. index:: Import library
If a Microsoft-style import library :file:`API.lib` or a GNAT-style
import library :file:`libAPI.dll.a` or :file:`libAPI.a` is available
with :file:`API.dll` you can skip this section. You can also skip this
section if :file:`API.dll` or :file:`libAPI.dll` is built with GNU tools
as in this case it is possible to link directly against the
DLL. Otherwise read on.
.. index:: Definition file
.. _The_Definition_File:
.. rubric:: The Definition File
As previously mentioned, and unlike Unix systems, the list of symbols
that are exported from a DLL must be provided explicitly in Windows.
The main goal of a definition file is precisely that: list the symbols
exported by a DLL. A definition file (usually a file with a `.def`
suffix) has the following structure:
::
[LIBRARY `name`]
[DESCRIPTION `string`]
EXPORTS
`symbol1`
`symbol2`
...
*LIBRARY `name`*
This section, which is optional, gives the name of the DLL.
*DESCRIPTION `string`*
This section, which is optional, gives a description string that will be
embedded in the import library.
*EXPORTS*
This section gives the list of exported symbols (procedures, functions or
variables). For instance in the case of :file:`API.dll` the `EXPORTS`
section of :file:`API.def` looks like:
::
EXPORTS
some_var
get
Note that you must specify the correct suffix (:samp:`@{nn}`)
(see :ref:`Windows_Calling_Conventions`) for a Stdcall
calling convention function in the exported symbols list.
There can actually be other sections in a definition file, but these
sections are not relevant to the discussion at hand.
.. rubric:: GNAT-Style Import Library
.. _GNAT-Style_Import_Library:
To create a static import library from :file:`API.dll` with the GNAT tools
you should proceed as follows:
* Create the definition file :file:`API.def`
(see :ref:`The Definition File <The_Definition_File>`).
For that use the `dll2def` tool as follows:
::
$ dll2def API.dll > API.def
`dll2def` is a very simple tool: it takes as input a DLL and prints
to standard output the list of entry points in the DLL. Note that if
some routines in the DLL have the `Stdcall` convention
(:ref:`Windows_Calling_Conventions`) with stripped :samp:`@{nn}`
suffix then you'll have to edit :file:`api.def` to add it, and specify
*-k* to *gnatdll* when creating the import library.
Here are some hints to find the right :samp:`@{nn}` suffix.
- If you have the Microsoft import library (.lib), it is possible to get
the right symbols by using Microsoft `dumpbin` tool (see the
corresponding Microsoft documentation for further details).
::
$ dumpbin /exports api.lib
- If you have a message about a missing symbol at link time the compiler
tells you what symbol is expected. You just have to go back to the
definition file and add the right suffix.
* Build the import library `libAPI.dll.a`, using `gnatdll`
(see :ref:`Using_gnatdll`) as follows:
::
$ gnatdll -e API.def -d API.dll
`gnatdll` takes as input a definition file :file:`API.def` and the
name of the DLL containing the services listed in the definition file
:file:`API.dll`. The name of the static import library generated is
computed from the name of the definition file as follows: if the
definition file name is `xyz``.def`, the import library name will
be `lib``xyz``.a`. Note that in the previous example option
*-e* could have been removed because the name of the definition
file (before the '`.def`' suffix) is the same as the name of the
DLL (:ref:`Using_gnatdll` for more information about `gnatdll`).
.. rubric:: Microsoft-Style Import Library
With GNAT you can either use a GNAT-style or Microsoft-style import
library. A Microsoft import library is needed only if you plan to make an
Ada DLL available to applications developed with Microsoft
tools (:ref:`Mixed-Language_Programming_on_Windows`).
To create a Microsoft-style import library for :file:`API.dll` you
should proceed as follows:
* Create the definition file :file:`API.def` from the DLL. For this use either
the `dll2def` tool as described above or the Microsoft `dumpbin`
tool (see the corresponding Microsoft documentation for further details).
* Build the actual import library using Microsoft's `lib` utility:
::
$ lib -machine:IX86 -def:API.def -out:API.lib
If you use the above command the definition file :file:`API.def` must
contain a line giving the name of the DLL:
::
LIBRARY "API"
See the Microsoft documentation for further details about the usage of
`lib`.
.. _Building_DLLs_with_GNAT_Project_files:
Building DLLs with GNAT Project files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: DLLs, building
There is nothing specific to Windows in the build process.
:ref:`Library_Projects`.
Due to a system limitation, it is not possible under Windows to create threads
when inside the `DllMain` routine which is used for auto-initialization
of shared libraries, so it is not possible to have library level tasks in SALs.
.. _Building_DLLs_with_GNAT:
Building DLLs with GNAT
^^^^^^^^^^^^^^^^^^^^^^^
.. index:: DLLs, building
This section explain how to build DLLs using the GNAT built-in DLL
support. With the following procedure it is straight forward to build
and use DLLs with GNAT.
* Building object files.
The first step is to build all objects files that are to be included
into the DLL. This is done by using the standard *gnatmake* tool.
* Building the DLL.
To build the DLL you must use *gcc*'s *-shared* and
*-shared-libgcc* options. It is quite simple to use this method:
::
$ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ...
It is important to note that in this case all symbols found in the
object files are automatically exported. It is possible to restrict
the set of symbols to export by passing to *gcc* a definition
file (see :ref:`The Definition File <The_Definition_File>`).
For example:
::
$ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ...
If you use a definition file you must export the elaboration procedures
for every package that required one. Elaboration procedures are named
using the package name followed by "_E".
* Preparing DLL to be used.
For the DLL to be used by client programs the bodies must be hidden
from it and the .ali set with read-only attribute. This is very important
otherwise GNAT will recompile all packages and will not actually use
the code in the DLL. For example:
::
$ mkdir apilib
$ copy *.ads *.ali api.dll apilib
$ attrib +R apilib\\*.ali
At this point it is possible to use the DLL by directly linking
against it. Note that you must use the GNAT shared runtime when using
GNAT shared libraries. This is achieved by using *-shared* binder's
option.
::
$ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI
.. _Building_DLLs_with_gnatdll:
Building DLLs with gnatdll
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: DLLs, building
Note that it is preferred to use GNAT Project files
(:ref:`Building_DLLs_with_GNAT_Project_files`) or the built-in GNAT
DLL support (:ref:`Building_DLLs_with_GNAT`) or to build DLLs.
This section explains how to build DLLs containing Ada code using
`gnatdll`. These DLLs will be referred to as Ada DLLs in the
remainder of this section.
The steps required to build an Ada DLL that is to be used by Ada as well as
non-Ada applications are as follows:
* You need to mark each Ada *entity* exported by the DLL with a `C` or
`Stdcall` calling convention to avoid any Ada name mangling for the
entities exported by the DLL
(see :ref:`Exporting Ada Entities <Exporting_Ada_Entities>`). You can
skip this step if you plan to use the Ada DLL only from Ada applications.
* Your Ada code must export an initialization routine which calls the routine
`adainit` generated by *gnatbind* to perform the elaboration of
the Ada code in the DLL (:ref:`Ada_DLLs_and_Elaboration`). The initialization
routine exported by the Ada DLL must be invoked by the clients of the DLL
to initialize the DLL.
* When useful, the DLL should also export a finalization routine which calls
routine `adafinal` generated by *gnatbind* to perform the
finalization of the Ada code in the DLL (:ref:`Ada_DLLs_and_Finalization`).
The finalization routine exported by the Ada DLL must be invoked by the
clients of the DLL when the DLL services are no further needed.
* You must provide a spec for the services exported by the Ada DLL in each
of the programming languages to which you plan to make the DLL available.
* You must provide a definition file listing the exported entities
(:ref:`The Definition File <The_Definition_File>`).
* Finally you must use `gnatdll` to produce the DLL and the import
library (:ref:`Using_gnatdll`).
Note that a relocatable DLL stripped using the `strip`
binutils tool will not be relocatable anymore. To build a DLL without
debug information pass `-largs -s` to `gnatdll`. This
restriction does not apply to a DLL built using a Library Project.
See :ref:`Library_Projects`.
.. Limitations_When_Using_Ada_DLLs_from Ada:
Limitations When Using Ada DLLs from Ada
""""""""""""""""""""""""""""""""""""""""
When using Ada DLLs from Ada applications there is a limitation users
should be aware of. Because on Windows the GNAT run time is not in a DLL of
its own, each Ada DLL includes a part of the GNAT run time. Specifically,
each Ada DLL includes the services of the GNAT run time that are necessary
to the Ada code inside the DLL. As a result, when an Ada program uses an
Ada DLL there are two independent GNAT run times: one in the Ada DLL and
one in the main program.
It is therefore not possible to exchange GNAT run-time objects between the
Ada DLL and the main Ada program. Example of GNAT run-time objects are file
handles (e.g., `Text_IO.File_Type`), tasks types, protected objects
types, etc.
It is completely safe to exchange plain elementary, array or record types,
Windows object handles, etc.
.. _Exporting_Ada_Entities:
Exporting Ada Entities
""""""""""""""""""""""
.. index:: Export table
Building a DLL is a way to encapsulate a set of services usable from any
application. As a result, the Ada entities exported by a DLL should be
exported with the `C` or `Stdcall` calling conventions to avoid
any Ada name mangling. As an example here is an Ada package
`API`, spec and body, exporting two procedures, a function, and a
variable:
.. code-block:: ada
with Interfaces.C; use Interfaces;
package API is
Count : C.int := 0;
function Factorial (Val : C.int) return C.int;
procedure Initialize_API;
procedure Finalize_API;
-- Initialization & Finalization routines. More in the next section.
private
pragma Export (C, Initialize_API);
pragma Export (C, Finalize_API);
pragma Export (C, Count);
pragma Export (C, Factorial);
end API;
.. code-block:: ada
package body API is
function Factorial (Val : C.int) return C.int is
Fact : C.int := 1;
begin
Count := Count + 1;
for K in 1 .. Val loop
Fact := Fact * K;
end loop;
return Fact;
end Factorial;
procedure Initialize_API is
procedure Adainit;
pragma Import (C, Adainit);
begin
Adainit;
end Initialize_API;
procedure Finalize_API is
procedure Adafinal;
pragma Import (C, Adafinal);
begin
Adafinal;
end Finalize_API;
end API;
If the Ada DLL you are building will only be used by Ada applications
you do not have to export Ada entities with a `C` or `Stdcall`
convention. As an example, the previous package could be written as
follows:
.. code-block:: ada
package API is
Count : Integer := 0;
function Factorial (Val : Integer) return Integer;
procedure Initialize_API;
procedure Finalize_API;
-- Initialization and Finalization routines.
end API;
.. code-block:: ada
package body API is
function Factorial (Val : Integer) return Integer is
Fact : Integer := 1;
begin
Count := Count + 1;
for K in 1 .. Val loop
Fact := Fact * K;
end loop;
return Fact;
end Factorial;
...
-- The remainder of this package body is unchanged.
end API;
Note that if you do not export the Ada entities with a `C` or
`Stdcall` convention you will have to provide the mangled Ada names
in the definition file of the Ada DLL
(:ref:`Creating_the_Definition_File`).
.. _Ada_DLLs_and_Elaboration:
Ada DLLs and Elaboration
""""""""""""""""""""""""
.. index:: DLLs and elaboration
The DLL that you are building contains your Ada code as well as all the
routines in the Ada library that are needed by it. The first thing a
user of your DLL must do is elaborate the Ada code
(:ref:`Elaboration_Order_Handling_in_GNAT`).
To achieve this you must export an initialization routine
(`Initialize_API` in the previous example), which must be invoked
before using any of the DLL services. This elaboration routine must call
the Ada elaboration routine `adainit` generated by the GNAT binder
(:ref:`Binding_with_Non-Ada_Main_Programs`). See the body of
`Initialize_Api` for an example. Note that the GNAT binder is
automatically invoked during the DLL build process by the `gnatdll`
tool (:ref:`Using_gnatdll`).
When a DLL is loaded, Windows systematically invokes a routine called
`DllMain`. It would therefore be possible to call `adainit`
directly from `DllMain` without having to provide an explicit
initialization routine. Unfortunately, it is not possible to call
`adainit` from the `DllMain` if your program has library level
tasks because access to the `DllMain` entry point is serialized by
the system (that is, only a single thread can execute 'through' it at a
time), which means that the GNAT run time will deadlock waiting for the
newly created task to complete its initialization.
.. _Ada_DLLs_and_Finalization:
Ada DLLs and Finalization
^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: DLLs and finalization
When the services of an Ada DLL are no longer needed, the client code should
invoke the DLL finalization routine, if available. The DLL finalization
routine is in charge of releasing all resources acquired by the DLL. In the
case of the Ada code contained in the DLL, this is achieved by calling
routine `adafinal` generated by the GNAT binder
(:ref:`Binding_with_Non-Ada_Main_Programs`).
See the body of `Finalize_Api` for an
example. As already pointed out the GNAT binder is automatically invoked
during the DLL build process by the `gnatdll` tool
(:ref:`Using_gnatdll`).
.. _Creating_a_Spec_for_Ada_DLLs:
Creating a Spec for Ada DLLs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To use the services exported by the Ada DLL from another programming
language (e.g., C), you have to translate the specs of the exported Ada
entities in that language. For instance in the case of `API.dll`,
the corresponding C header file could look like:
.. code-block:: c
extern int *_imp__count;
#define count (*_imp__count)
int factorial (int);
It is important to understand that when building an Ada DLL to be used by
other Ada applications, you need two different specs for the packages
contained in the DLL: one for building the DLL and the other for using
the DLL. This is because the `DLL` calling convention is needed to
use a variable defined in a DLL, but when building the DLL, the variable
must have either the `Ada` or `C` calling convention. As an
example consider a DLL comprising the following package `API`:
.. code-block:: ada
package API is
Count : Integer := 0;
...
-- Remainder of the package omitted.
end API;
After producing a DLL containing package `API`, the spec that
must be used to import `API.Count` from Ada code outside of the
DLL is:
.. code-block:: ada
package API is
Count : Integer;
pragma Import (DLL, Count);
end API;
.. _Creating_the_Definition_File:
Creating the Definition File
""""""""""""""""""""""""""""
The definition file is the last file needed to build the DLL. It lists
the exported symbols. As an example, the definition file for a DLL
containing only package `API` (where all the entities are exported
with a `C` calling convention) is:
::
EXPORTS
count
factorial
finalize_api
initialize_api
If the `C` calling convention is missing from package `API`,
then the definition file contains the mangled Ada names of the above
entities, which in this case are:
::
EXPORTS
api__count
api__factorial
api__finalize_api
api__initialize_api
.. _Using_gnatdll:
Using `gnatdll`
"""""""""""""""
.. index:: gnatdll
`gnatdll` is a tool to automate the DLL build process once all the Ada
and non-Ada sources that make up your DLL have been compiled.
`gnatdll` is actually in charge of two distinct tasks: build the
static import library for the DLL and the actual DLL. The form of the
`gnatdll` command is
::
$ gnatdll [`switches`] `list-of-files` [-largs `opts`]
where `list-of-files` is a list of ALI and object files. The object
file list must be the exact list of objects corresponding to the non-Ada
sources whose services are to be included in the DLL. The ALI file list
must be the exact list of ALI files for the corresponding Ada sources
whose services are to be included in the DLL. If `list-of-files` is
missing, only the static import library is generated.
You may specify any of the following switches to `gnatdll`:
.. index:: -a (gnatdll)
:samp:`-a[{address}]`
Build a non-relocatable DLL at `address`. If `address` is not
specified the default address `0x11000000` will be used. By default,
when this switch is missing, `gnatdll` builds relocatable DLL. We
advise the reader to build relocatable DLL.
.. index:: -b (gnatdll)
:samp:`-b {address}`
Set the relocatable DLL base address. By default the address is
`0x11000000`.
.. index:: -bargs (gnatdll)
:samp:`-bargs {opts}`
Binder options. Pass `opts` to the binder.
.. index:: -d (gnatdll)
:samp:`-d {dllfile}`
`dllfile` is the name of the DLL. This switch must be present for
`gnatdll` to do anything. The name of the generated import library is
obtained algorithmically from `dllfile` as shown in the following
example: if `dllfile` is `xyz.dll`, the import library name is
`libxyz.dll.a`. The name of the definition file to use (if not specified
by option *-e*) is obtained algorithmically from `dllfile`
as shown in the following example:
if `dllfile` is `xyz.dll`, the definition
file used is `xyz.def`.
.. index:: -e (gnatdll)
:samp:`-e {deffile}`
`deffile` is the name of the definition file.
.. index:: -g (gnatdll)
:samp:`-g`
Generate debugging information. This information is stored in the object
file and copied from there to the final DLL file by the linker,
where it can be read by the debugger. You must use the
*-g* switch if you plan on using the debugger or the symbolic
stack traceback.
.. index:: -h (gnatdll)
:samp:`-h`
Help mode. Displays `gnatdll` switch usage information.
.. index:: -I (gnatdll)
:samp:`-I{dir}`
Direct `gnatdll` to search the `dir` directory for source and
object files needed to build the DLL.
(:ref:`Search_Paths_and_the_Run-Time_Library_RTL`).
.. index:: -k (gnatdll)
:samp:`-k`
Removes the :samp:`@{nn}` suffix from the import library's exported
names, but keeps them for the link names. You must specify this
option if you want to use a `Stdcall` function in a DLL for which
the :samp:`@{nn}` suffix has been removed. This is the case for most
of the Windows NT DLL for example. This option has no effect when
*-n* option is specified.
.. index:: -l (gnatdll)
:samp:`-l {file}`
The list of ALI and object files used to build the DLL are listed in
`file`, instead of being given in the command line. Each line in
`file` contains the name of an ALI or object file.
.. index:: -n (gnatdll)
:samp:`-n`
No Import. Do not create the import library.
.. index:: -q (gnatdll)
:samp:`-q`
Quiet mode. Do not display unnecessary messages.
.. index:: -v (gnatdll)
:samp:`-v`
Verbose mode. Display extra information.
.. index:: -largs (gnatdll)
:samp:`-largs {opts}`
Linker options. Pass `opts` to the linker.
.. rubric:: `gnatdll` Example
As an example the command to build a relocatable DLL from :file:`api.adb`
once :file:`api.adb` has been compiled and :file:`api.def` created is
::
$ gnatdll -d api.dll api.ali
The above command creates two files: :file:`libapi.dll.a` (the import
library) and :file:`api.dll` (the actual DLL). If you want to create
only the DLL, just type:
::
$ gnatdll -d api.dll -n api.ali
Alternatively if you want to create just the import library, type:
::
$ gnatdll -d api.dll
.. rubric:: `gnatdll` behind the Scenes
This section details the steps involved in creating a DLL. `gnatdll`
does these steps for you. Unless you are interested in understanding what
goes on behind the scenes, you should skip this section.
We use the previous example of a DLL containing the Ada package `API`,
to illustrate the steps necessary to build a DLL. The starting point is a
set of objects that will make up the DLL and the corresponding ALI
files. In the case of this example this means that :file:`api.o` and
:file:`api.ali` are available. To build a relocatable DLL, `gnatdll` does
the following:
* `gnatdll` builds the base file (:file:`api.base`). A base file gives
the information necessary to generate relocation information for the
DLL.
::
$ gnatbind -n api
$ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base
In addition to the base file, the *gnatlink* command generates an
output file :file:`api.jnk` which can be discarded. The *-mdll* switch
asks *gnatlink* to generate the routines `DllMain` and
`DllMainCRTStartup` that are called by the Windows loader when the DLL
is loaded into memory.
* `gnatdll` uses `dlltool` (see :ref:`Using dlltool <Using_dlltool>`) to build the
export table (:file:`api.exp`). The export table contains the relocation
information in a form which can be used during the final link to ensure
that the Windows loader is able to place the DLL anywhere in memory.
::
$ dlltool --dllname api.dll --def api.def --base-file api.base \\
--output-exp api.exp
* `gnatdll` builds the base file using the new export table. Note that
*gnatbind* must be called once again since the binder generated file
has been deleted during the previous call to *gnatlink*.
::
$ gnatbind -n api
$ gnatlink api -o api.jnk api.exp -mdll
-Wl,--base-file,api.base
* `gnatdll` builds the new export table using the new base file and
generates the DLL import library :file:`libAPI.dll.a`.
::
$ dlltool --dllname api.dll --def api.def --base-file api.base \\
--output-exp api.exp --output-lib libAPI.a
* Finally `gnatdll` builds the relocatable DLL using the final export
table.
::
$ gnatbind -n api
$ gnatlink api api.exp -o api.dll -mdll
.. _Using_dlltool:
.. rubric:: Using `dlltool`
`dlltool` is the low-level tool used by `gnatdll` to build
DLLs and static import libraries. This section summarizes the most
common `dlltool` switches. The form of the `dlltool` command
is
::
$ dlltool [`switches`]
`dlltool` switches include:
.. index:: --base-file (dlltool)
:samp:`--base-file {basefile}`
Read the base file `basefile` generated by the linker. This switch
is used to create a relocatable DLL.
.. index:: --def (dlltool)
:samp:`--def {deffile}`
Read the definition file.
.. index:: --dllname (dlltool)
:samp:`--dllname {name}`
Gives the name of the DLL. This switch is used to embed the name of the
DLL in the static import library generated by `dlltool` with switch
*--output-lib*.
.. index:: -k (dlltool)
:samp:`-k`
Kill :samp:`@{nn}` from exported names
(:ref:`Windows_Calling_Conventions`
for a discussion about `Stdcall`-style symbols.
.. index:: --help (dlltool)
:samp:`--help`
Prints the `dlltool` switches with a concise description.
.. index:: --output-exp (dlltool)
:samp:`--output-exp {exportfile}`
Generate an export file `exportfile`. The export file contains the
export table (list of symbols in the DLL) and is used to create the DLL.
.. index:: --output-lib (dlltool)
:samp:`--output-lib {libfile}`
Generate a static import library `libfile`.
.. index:: -v (dlltool)
:samp:`-v`
Verbose mode.
.. index:: --as (dlltool)
:samp:`--as {assembler-name}`
Use `assembler-name` as the assembler. The default is `as`.
.. _GNAT_and_Windows_Resources:
GNAT and Windows Resources
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. index:: Resources, windows
Resources are an easy way to add Windows specific objects to your
application. The objects that can be added as resources include:
* menus
* accelerators
* dialog boxes
* string tables
* bitmaps
* cursors
* icons
* fonts
* version information
For example, a version information resource can be defined as follow and
embedded into an executable or DLL:
A version information resource can be used to embed information into an
executable or a DLL. These information can be viewed using the file properties
from the Windows Explorer. Here is an example of a version information
resource:
::
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904E4"
BEGIN
VALUE "CompanyName", "My Company Name"
VALUE "FileDescription", "My application"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "my_app"
VALUE "LegalCopyright", "My Name"
VALUE "OriginalFilename", "my_app.exe"
VALUE "ProductName", "My App"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1252
END
END
The value `0809` (langID) is for the U.K English language and
`04E4` (charsetID), which is equal to `1252` decimal, for
multilingual.
This section explains how to build, compile and use resources. Note that this
section does not cover all resource objects, for a complete description see
the corresponding Microsoft documentation.
.. _Building_Resources:
Building Resources
""""""""""""""""""
.. index:: Resources, building
A resource file is an ASCII file. By convention resource files have an
:file:`.rc` extension.
The easiest way to build a resource file is to use Microsoft tools
such as `imagedit.exe` to build bitmaps, icons and cursors and
`dlgedit.exe` to build dialogs.
It is always possible to build an :file:`.rc` file yourself by writing a
resource script.
It is not our objective to explain how to write a resource file. A
complete description of the resource script language can be found in the
Microsoft documentation.
.. _Compiling_Resources:
Compiling Resources
"""""""""""""""""""
.. index:: rc
.. index:: windres
.. index:: Resources, compiling
This section describes how to build a GNAT-compatible (COFF) object file
containing the resources. This is done using the Resource Compiler
`windres` as follows:
::
$ windres -i myres.rc -o myres.o
By default `windres` will run *gcc* to preprocess the :file:`.rc`
file. You can specify an alternate preprocessor (usually named
:file:`cpp.exe`) using the `windres` *--preprocessor*
parameter. A list of all possible options may be obtained by entering
the command `windres` *--help*.
It is also possible to use the Microsoft resource compiler `rc.exe`
to produce a :file:`.res` file (binary resource file). See the
corresponding Microsoft documentation for further details. In this case
you need to use `windres` to translate the :file:`.res` file to a
GNAT-compatible object file as follows:
::
$ windres -i myres.res -o myres.o
.. _Using_Resources:
Using Resources
"""""""""""""""
.. index:: Resources, using
To include the resource file in your program just add the
GNAT-compatible object file for the resource(s) to the linker
arguments. With *gnatmake* this is done by using the *-largs*
option:
::
$ gnatmake myprog -largs myres.o
.. _Debugging_a_DLL:
Debugging a DLL
^^^^^^^^^^^^^^^
.. index:: DLL debugging
Debugging a DLL is similar to debugging a standard program. But
we have to deal with two different executable parts: the DLL and the
program that uses it. We have the following four possibilities:
* The program and the DLL are built with `GCC/GNAT`.
* The program is built with foreign tools and the DLL is built with
`GCC/GNAT`.
* The program is built with `GCC/GNAT` and the DLL is built with
foreign tools.
In this section we address only cases one and two above.
There is no point in trying to debug
a DLL with `GNU/GDB`, if there is no GDB-compatible debugging
information in it. To do so you must use a debugger compatible with the
tools suite used to build the DLL.
.. _Program_and_DLL_Both_Built_with_GCC/GNAT:
Program and DLL Both Built with GCC/GNAT
""""""""""""""""""""""""""""""""""""""""
This is the simplest case. Both the DLL and the program have `GDB`
compatible debugging information. It is then possible to break anywhere in
the process. Let's suppose here that the main procedure is named
`ada_main` and that in the DLL there is an entry point named
`ada_dll`.
The DLL (:ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) and
program must have been built with the debugging information (see GNAT -g
switch). Here are the step-by-step instructions for debugging it:
* Launch `GDB` on the main program.
::
$ gdb -nw ada_main
* Start the program and stop at the beginning of the main procedure
::
(gdb) start
This step is required to be able to set a breakpoint inside the DLL. As long
as the program is not run, the DLL is not loaded. This has the
consequence that the DLL debugging information is also not loaded, so it is not
possible to set a breakpoint in the DLL.
* Set a breakpoint inside the DLL
::
(gdb) break ada_dll
(gdb) cont
At this stage a breakpoint is set inside the DLL. From there on
you can use the standard approach to debug the whole program
(:ref:`Running_and_Debugging_Ada_Programs`).
.. _Program_Built_with_Foreign_Tools_and_DLL_Built_with_GCC/GNAT:
Program Built with Foreign Tools and DLL Built with GCC/GNAT
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
In this case things are slightly more complex because it is not possible to
start the main program and then break at the beginning to load the DLL and the
associated DLL debugging information. It is not possible to break at the
beginning of the program because there is no `GDB` debugging information,
and therefore there is no direct way of getting initial control. This
section addresses this issue by describing some methods that can be used
to break somewhere in the DLL to debug it.
First suppose that the main procedure is named `main` (this is for
example some C code built with Microsoft Visual C) and that there is a
DLL named `test.dll` containing an Ada entry point named
`ada_dll`.
The DLL (see :ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) must have
been built with debugging information (see GNAT `-g` option).
.. rubric:: Debugging the DLL Directly
* Find out the executable starting address
::
$ objdump --file-header main.exe
The starting address is reported on the last line. For example:
::
main.exe: file format pei-i386
architecture: i386, flags 0x0000010a:
EXEC_P, HAS_DEBUG, D_PAGED
start address 0x00401010
* Launch the debugger on the executable.
::
$ gdb main.exe
* Set a breakpoint at the starting address, and launch the program.
::
$ (gdb) break *0x00401010
$ (gdb) run
The program will stop at the given address.
* Set a breakpoint on a DLL subroutine.
::
(gdb) break ada_dll.adb:45
Or if you want to break using a symbol on the DLL, you need first to
select the Ada language (language used by the DLL).
::
(gdb) set language ada
(gdb) break ada_dll
* Continue the program.
::
(gdb) cont
This will run the program until it reaches the breakpoint that has been
set. From that point you can use the standard way to debug a program
as described in (:ref:`Running_and_Debugging_Ada_Programs`).
It is also possible to debug the DLL by attaching to a running process.
.. rubric:: Attaching to a Running Process
.. index:: DLL debugging, attach to process
With `GDB` it is always possible to debug a running process by
attaching to it. It is possible to debug a DLL this way. The limitation
of this approach is that the DLL must run long enough to perform the
attach operation. It may be useful for instance to insert a time wasting
loop in the code of the DLL to meet this criterion.
* Launch the main program :file:`main.exe`.
::
$ main
* Use the Windows *Task Manager* to find the process ID. Let's say
that the process PID for :file:`main.exe` is 208.
* Launch gdb.
::
$ gdb
* Attach to the running process to be debugged.
::
(gdb) attach 208
* Load the process debugging information.
::
(gdb) symbol-file main.exe
* Break somewhere in the DLL.
::
(gdb) break ada_dll
* Continue process execution.
::
(gdb) cont
This last step will resume the process execution, and stop at
the breakpoint we have set. From there you can use the standard
approach to debug a program as described in
:ref:`Running_and_Debugging_Ada_Programs`.
.. _Setting_Stack_Size_from_gnatlink:
Setting Stack Size from *gnatlink*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is possible to specify the program stack size at link time. On modern
versions of Windows, starting with XP, this is mostly useful to set the size of
the main stack (environment task). The other task stacks are set with pragma
Storage_Size or with the *gnatbind -d* command.
Since older versions of Windows (2000, NT4, etc.) do not allow setting the
reserve size of individual tasks, the link-time stack size applies to all
tasks, and pragma Storage_Size has no effect.
In particular, Stack Overflow checks are made against this
link-time specified size.
This setting can be done with *gnatlink* using either of the following:
* *-Xlinker* linker option
::
$ gnatlink hello -Xlinker --stack=0x10000,0x1000
This sets the stack reserve size to 0x10000 bytes and the stack commit
size to 0x1000 bytes.
* *-Wl* linker option
::
$ gnatlink hello -Wl,--stack=0x1000000
This sets the stack reserve size to 0x1000000 bytes. Note that with
*-Wl* option it is not possible to set the stack commit size
because the coma is a separator for this option.
.. _Setting_Heap_Size_from_gnatlink:
Setting Heap Size from *gnatlink*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Under Windows systems, it is possible to specify the program heap size from
*gnatlink* using either of the following:
* *-Xlinker* linker option
::
$ gnatlink hello -Xlinker --heap=0x10000,0x1000
This sets the heap reserve size to 0x10000 bytes and the heap commit
size to 0x1000 bytes.
* *-Wl* linker option
::
$ gnatlink hello -Wl,--heap=0x1000000
This sets the heap reserve size to 0x1000000 bytes. Note that with
*-Wl* option it is not possible to set the heap commit size
because the coma is a separator for this option.
.. _Mac_OS_Topics:
Mac OS Topics
=============
.. index:: OS X
This section describes topics that are specific to Apple's OS X
platform.
Codesigning the Debugger
------------------------
The Darwin Kernel requires the debugger to have special permissions
before it is allowed to control other processes. These permissions
are granted by codesigning the GDB executable. Without these
permissions, the debugger will report error messages such as::
Starting program: /x/y/foo
Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5).
(please check gdb is codesigned - see taskgated(8))
Codesigning requires a certificate. The following procedure explains
how to create one:
* Start the Keychain Access application (in
/Applications/Utilities/Keychain Access.app)
* Select the Keychain Access -> Certificate Assistant ->
Create a Certificate... menu
* Then:
* Choose a name for the new certificate (this procedure will use
"gdb-cert" as an example)
* Set "Identity Type" to "Self Signed Root"
* Set "Certificate Type" to "Code Signing"
* Activate the "Let me override defaults" option
* Click several times on "Continue" until the "Specify a Location
For The Certificate" screen appears, then set "Keychain" to "System"
* Click on "Continue" until the certificate is created
* Finally, in the view, double-click on the new certificate,
and set "When using this certificate" to "Always Trust"
* Exit the Keychain Access application and restart the computer
(this is unfortunately required)
Once a certificate has been created, the debugger can be codesigned
as follow. In a Terminal, run the following command:
::
$ codesign -f -s "gdb-cert" <gnat_install_prefix>/bin/gdb
where "gdb-cert" should be replaced by the actual certificate
name chosen above, and <gnat_install_prefix> should be replaced by
the location where you installed GNAT. Also, be sure that users are
in the Unix group ``_developer``.
This source diff could not be displayed because it is too large. You can view the blob instead.
.. _Tools_Supporting_Project_Files:
Tools Supporting Project Files
==============================
This section describes how project files can be used in conjunction with a number of
GNAT tools.
.. _gnatmake_and_Project_Files:
gnatmake and Project Files
--------------------------
This section covers several topics related to *gnatmake* and
project files: defining switches for *gnatmake*
and for the tools that it invokes; specifying configuration pragmas;
the use of the `Main` attribute; building and rebuilding library project
files.
.. _Switches_Related_to_Project_Files:
Switches Related to Project Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following switches are used by GNAT tools that support project files:
.. index:: -P (any project-aware tool)
:samp:`-P{project}`
Indicates the name of a project file. This project file will be parsed with
the verbosity indicated by *-vP*x**,
if any, and using the external references indicated
by *-X* switches, if any.
There may zero, one or more spaces between *-P* and `project`.
There must be only one *-P* switch on the command line.
Since the Project Manager parses the project file only after all the switches
on the command line are checked, the order of the switches
*-P*,
*-vP*x**
or *-X* is not significant.
.. index:: -X (any project-aware tool)
:samp:`-X{name}={value}`
Indicates that external variable `name` has the value `value`.
The Project Manager will use this value for occurrences of
`external(name)` when parsing the project file.
If `name` or `value` includes a space, then `name=value` should be
put between quotes.
::
-XOS=NT
-X"user=John Doe"
Several *-X* switches can be used simultaneously.
If several *-X* switches specify the same
`name`, only the last one is used.
An external variable specified with a *-X* switch
takes precedence over the value of the same name in the environment.
.. index:: -vP (any project-aware tool)
:samp:`-vP{x}`
Indicates the verbosity of the parsing of GNAT project files.
*-vP0* means Default;
*-vP1* means Medium;
*-vP2* means High.
The default is Default: no output for syntactically correct
project files.
If several *-vP*x** switches are present,
only the last one is used.
.. index:: -aP (any project-aware tool)
:samp:`-aP{dir}`
Add directory `dir` at the beginning of the project search path, in order,
after the current working directory.
.. index:: -eL (any project-aware tool)
:samp:`-eL`
Follow all symbolic links when processing project files.
.. index:: --subdirs= (gnatmake and gnatclean)
:samp:`--subdirs={subdir}`
This switch is recognized by *gnatmake* and *gnatclean*. It
indicate that the real directories (except the source directories) are the
subdirectories `subdir` of the directories specified in the project files.
This applies in particular to object directories, library directories and
exec directories. If the subdirectories do not exist, they are created
automatically.
.. _Switches_and_Project_Files:
Switches and Project Files
^^^^^^^^^^^^^^^^^^^^^^^^^^
For each of the packages `Builder`, `Compiler`, `Binder`, and
`Linker`, you can specify a `Default_Switches`
attribute, a `Switches` attribute, or both;
as their names imply, these switch-related
attributes affect the switches that are used for each of these GNAT
components when
*gnatmake* is invoked. As will be explained below, these
component-specific switches precede
the switches provided on the *gnatmake* command line.
The `Default_Switches` attribute is an attribute
indexed by language name (case insensitive) whose value is a string list.
For example:
.. code-block:: gpr
package Compiler is
for Default_Switches ("Ada")
use ("-gnaty",
"-v");
end Compiler;
The `Switches` attribute is indexed on a file name (which may or may
not be case sensitive, depending
on the operating system) whose value is a string list. For example:
.. code-block:: gpr
package Builder is
for Switches ("main1.adb")
use ("-O2");
for Switches ("main2.adb")
use ("-g");
end Builder;
For the `Builder` package, the file names must designate source files
for main subprograms. For the `Binder` and `Linker` packages, the
file names must designate :file:`ALI` or source files for main subprograms.
In each case just the file name without an explicit extension is acceptable.
For each tool used in a program build (*gnatmake*, the compiler, the
binder, and the linker), the corresponding package @dfn{contributes} a set of
switches for each file on which the tool is invoked, based on the
switch-related attributes defined in the package.
In particular, the switches
that each of these packages contributes for a given file `f` comprise:
* the value of attribute `Switches (`f`)`,
if it is specified in the package for the given file,
* otherwise, the value of `Default_Switches ("Ada")`,
if it is specified in the package.
If neither of these attributes is defined in the package, then the package does
not contribute any switches for the given file.
When *gnatmake* is invoked on a file, the switches comprise
two sets, in the following order: those contributed for the file
by the `Builder` package;
and the switches passed on the command line.
When *gnatmake* invokes a tool (compiler, binder, linker) on a file,
the switches passed to the tool comprise three sets,
in the following order:
* the applicable switches contributed for the file
by the `Builder` package in the project file supplied on the command line;
* those contributed for the file by the package (in the relevant project file --
see below) corresponding to the tool; and
* the applicable switches passed on the command line.
The term *applicable switches* reflects the fact that
*gnatmake* switches may or may not be passed to individual
tools, depending on the individual switch.
*gnatmake* may invoke the compiler on source files from different
projects. The Project Manager will use the appropriate project file to
determine the `Compiler` package for each source file being compiled.
Likewise for the `Binder` and `Linker` packages.
As an example, consider the following package in a project file:
.. code-block:: gpr
project Proj1 is
package Compiler is
for Default_Switches ("Ada")
use ("-g");
for Switches ("a.adb")
use ("-O1");
for Switches ("b.adb")
use ("-O2",
"-gnaty");
end Compiler;
end Proj1;
If *gnatmake* is invoked with this project file, and it needs to
compile, say, the files :file:`a.adb`, :file:`b.adb`, and :file:`c.adb`, then
:file:`a.adb` will be compiled with the switch *-O1*,
:file:`b.adb` with switches *-O2* and *-gnaty*,
and :file:`c.adb` with *-g*.
The following example illustrates the ordering of the switches
contributed by different packages:
.. code-block:: gpr
project Proj2 is
package Builder is
for Switches ("main.adb")
use ("-g",
"-O1",
"-f");
end Builder;
package Compiler is
for Switches ("main.adb")
use ("-O2");
end Compiler;
end Proj2;
If you issue the command:
::
$ gnatmake -Pproj2 -O0 main
then the compiler will be invoked on :file:`main.adb` with the following
sequence of switches
::
-g -O1 -O2 -O0
with the last *-O*
switch having precedence over the earlier ones;
several other switches
(such as *-c*) are added implicitly.
The switches *-g*
and *-O1* are contributed by package
`Builder`, *-O2* is contributed
by the package `Compiler`
and *-O0* comes from the command line.
The *-g* switch will also be passed in the invocation of
*Gnatlink.*
A final example illustrates switch contributions from packages in different
project files:
.. code-block:: gpr
project Proj3 is
for Source_Files use ("pack.ads", "pack.adb");
package Compiler is
for Default_Switches ("Ada")
use ("-gnata");
end Compiler;
end Proj3;
with "Proj3";
project Proj4 is
for Source_Files use ("foo_main.adb", "bar_main.adb");
package Builder is
for Switches ("foo_main.adb")
use ("-s",
"-g");
end Builder;
end Proj4;
.. code-block:: ada
-- Ada source file:
with Pack;
procedure Foo_Main is
...
end Foo_Main;
If the command is
::
$ gnatmake -PProj4 foo_main.adb -cargs -gnato
then the switches passed to the compiler for :file:`foo_main.adb` are
*-g* (contributed by the package `Proj4.Builder`) and
*-gnato* (passed on the command line).
When the imported package `Pack` is compiled, the switches used
are *-g* from `Proj4.Builder`,
*-gnata* (contributed from package `Proj3.Compiler`,
and *-gnato* from the command line.
When using *gnatmake* with project files, some switches or
arguments may be expressed as relative paths. As the working directory where
compilation occurs may change, these relative paths are converted to absolute
paths. For the switches found in a project file, the relative paths
are relative to the project file directory, for the switches on the command
line, they are relative to the directory where *gnatmake* is invoked.
The switches for which this occurs are:
-I,
-A,
-L,
-aO,
-aL,
-aI, as well as all arguments that are not switches (arguments to
switch
-o, object files specified in package `Linker` or after
-largs on the command line). The exception to this rule is the switch
--RTS= for which a relative path argument is never converted.
.. _Specifying_Configuration_Pragmas:
Specifying Configuration Pragmas
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When using *gnatmake* with project files, if there exists a file
:file:`gnat.adc` that contains configuration pragmas, this file will be
ignored.
Configuration pragmas can be defined by means of the following attributes in
project files: `Global_Configuration_Pragmas` in package `Builder`
and `Local_Configuration_Pragmas` in package `Compiler`.
Both these attributes are single string attributes. Their values is the path
name of a file containing configuration pragmas. If a path name is relative,
then it is relative to the project directory of the project file where the
attribute is defined.
When compiling a source, the configuration pragmas used are, in order,
those listed in the file designated by attribute
`Global_Configuration_Pragmas` in package `Builder` of the main
project file, if it is specified, and those listed in the file designated by
attribute `Local_Configuration_Pragmas` in package `Compiler` of
the project file of the source, if it exists.
.. _Project_Files_and_Main_Subprograms:
Project Files and Main Subprograms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When using a project file, you can invoke *gnatmake*
with one or several main subprograms, by specifying their source files on the
command line.
::
$ gnatmake -Pprj main1.adb main2.adb main3.adb
Each of these needs to be a source file of the same project, except
when the switch `-u` is used.
When `-u` is not used, all the mains need to be sources of the
same project, one of the project in the tree rooted at the project specified
on the command line. The package `Builder` of this common project, the
"main project" is the one that is considered by *gnatmake*.
When `-u` is used, the specified source files may be in projects
imported directly or indirectly by the project specified on the command line.
Note that if such a source file is not part of the project specified on the
command line, the switches found in package `Builder` of the
project specified on the command line, if any, that are transmitted
to the compiler will still be used, not those found in the project file of
the source file.
When using a project file, you can also invoke *gnatmake* without
explicitly specifying any main, and the effect depends on whether you have
defined the `Main` attribute. This attribute has a string list value,
where each element in the list is the name of a source file (the file
extension is optional) that contains a unit that can be a main subprogram.
If the `Main` attribute is defined in a project file as a non-empty
string list and the switch *-u* is not used on the command
line, then invoking *gnatmake* with this project file but without any
main on the command line is equivalent to invoking *gnatmake* with all
the file names in the `Main` attribute on the command line.
Example:
.. code-block:: gpr
project Prj is
for Main use ("main1.adb", "main2.adb", "main3.adb");
end Prj;
With this project file, `"gnatmake -Pprj"`
is equivalent to
`"gnatmake -Pprj main1.adb main2.adb main3.adb"`.
When the project attribute `Main` is not specified, or is specified
as an empty string list, or when the switch *-u* is used on the command
line, then invoking *gnatmake* with no main on the command line will
result in all immediate sources of the project file being checked, and
potentially recompiled. Depending on the presence of the switch *-u*,
sources from other project files on which the immediate sources of the main
project file depend are also checked and potentially recompiled. In other
words, the *-u* switch is applied to all of the immediate sources of the
main project file.
When no main is specified on the command line and attribute `Main` exists
and includes several mains, or when several mains are specified on the
command line, the default switches in package `Builder` will
be used for all mains, even if there are specific switches
specified for one or several mains.
But the switches from package `Binder` or `Linker` will be
the specific switches for each main, if they are specified.
.. _Library_Project_Files:
Library Project Files
^^^^^^^^^^^^^^^^^^^^^
When *gnatmake* is invoked with a main project file that is a library
project file, it is not allowed to specify one or more mains on the command
line.
When a library project file is specified, switches `-b` and
`-l` have special meanings.
* `-b` is only allowed for stand-alone libraries. It indicates
to *gnatmake* that *gnatbind* should be invoked for the
library.
* `-l` may be used for all library projects. It indicates
to *gnatmake* that the binder generated file should be compiled
(in the case of a stand-alone library) and that the library should be built.
.. _The_GNAT_Driver_and_Project_Files:
The GNAT Driver and Project Files
---------------------------------
A number of GNAT tools beyond *gnatmake*
can benefit from project files:
.. only:: PRO or GPL
* *gnatbind*
* *gnatcheck*
* *gnatclean*
* *gnatelim*
* *gnatfind*
* *gnatlink*
* *gnatls*
* *gnatmetric*
* *gnatpp*
* *gnatstub*
* *gnatxref*
.. only:: FSF
* *gnatbind*
* *gnatclean*
* *gnatfind*
* *gnatlink*
* *gnatls*
* *gnatxref*
However, none of these tools can be invoked
directly with a project file switch (*-P*).
They must be invoked through the *gnat* driver.
The *gnat* driver is a wrapper that accepts a number of commands and
calls the corresponding tool. It was designed initially for VMS platforms (to
convert VMS qualifiers to Unix-style switches), but it is now available on all
GNAT platforms.
On non-VMS platforms, the *gnat* driver accepts the following commands
(case insensitive):
.. only:: PRO or GPL
* BIND to invoke *gnatbind*
* CHOP to invoke *gnatchop*
* CLEAN to invoke *gnatclean*
* COMP or COMPILE to invoke the compiler
* ELIM to invoke *gnatelim*
* FIND to invoke *gnatfind*
* KR or KRUNCH to invoke *gnatkr*
* LINK to invoke *gnatlink*
* LS or LIST to invoke *gnatls*
* MAKE to invoke *gnatmake*
* METRIC to invoke *gnatmetric*
* NAME to invoke *gnatname*
* PP or PRETTY to invoke *gnatpp*
* PREP or PREPROCESS to invoke *gnatprep*
* STUB to invoke *gnatstub*
* XREF to invoke *gnatxref*
.. only:: FSF
* BIND to invoke *gnatbind*
* CHOP to invoke *gnatchop*
* CLEAN to invoke *gnatclean*
* COMP or COMPILE to invoke the compiler
* FIND to invoke *gnatfind*
* KR or KRUNCH to invoke *gnatkr*
* LINK to invoke *gnatlink*
* LS or LIST to invoke *gnatls*
* MAKE to invoke *gnatmake*
* NAME to invoke *gnatname*
* PREP or PREPROCESS to invoke *gnatprep*
* XREF to invoke *gnatxref*
Note that the command
*gnatmake -c -f -u* is used to invoke the compiler.
On non-VMS platforms, between *gnat* and the command, two
special switches may be used:
* *-v* to display the invocation of the tool.
* *-dn* to prevent the *gnat* driver from removing
the temporary files it has created. These temporary files are
configuration files and temporary file list files.
The command may be followed by switches and arguments for the invoked
tool.
::
$ gnat bind -C main.ali
$ gnat ls -a main
$ gnat chop foo.txt
Switches may also be put in text files, one switch per line, and the text
files may be specified with their path name preceded by '@'.
::
$ gnat bind @args.txt main.ali
In addition, for the following commands the project file related switches
(*-P*, *-X* and *-vPx*) may be used in addition to
the switches of the invoking tool:
.. only:: PRO or GPL
* BIND
* COMP or COMPILE
* FIND
* ELIM
* LS or LIST
* LINK
* METRIC
* PP or PRETTY
* STUB
* XREF
.. only:: FSF
* BIND
* COMP or COMPILE
* FIND
* LS or LIST
* LINK
* XREF
.. only:: PRO or GPL
When GNAT PP or GNAT PRETTY is used with a project file, but with no source
specified on the command line, it invokes *gnatpp* with all
the immediate sources of the specified project file.
When GNAT METRIC is used with a project file, but with no source
specified on the command line, it invokes *gnatmetric*
with all the immediate sources of the specified project file and with
*-d* with the parameter pointing to the object directory
of the project.
In addition, when GNAT PP, GNAT PRETTY or GNAT METRIC is used with
a project file, no source is specified on the command line and
switch -U is specified on the command line, then
the underlying tool (gnatpp or
gnatmetric) is invoked for all sources of all projects,
not only for the immediate sources of the main project.
(-U stands for Universal or Union of the project files of the project tree)
For each of the following commands, there is optionally a corresponding
package in the main project.
.. only:: PRO or GPL
* package `Binder` for command BIND (invoking `gnatbind`)
* package `Check` for command CHECK (invoking `gnatcheck`)
* package `Compiler` for command COMP or COMPILE (invoking the compiler)
* package `Cross_Reference` for command XREF (invoking `gnatxref`)
* package `Eliminate` for command ELIM (invoking `gnatelim`)
* package `Finder` for command FIND (invoking `gnatfind`)
* package `Gnatls` for command LS or LIST (invoking `gnatls`)
* package `Gnatstub` for command STUB (invoking `gnatstub`)
* package `Linker` for command LINK (invoking `gnatlink`)
* package `Metrics` for command METRIC (invoking `gnatmetric`)
* package `Pretty_Printer` for command PP or PRETTY (invoking `gnatpp`)
.. only:: FSF
* package `Binder` for command BIND (invoking `gnatbind`)
* package `Compiler` for command COMP or COMPILE (invoking the compiler)
* package `Cross_Reference` for command XREF (invoking `gnatxref`)
* package `Finder` for command FIND (invoking `gnatfind`)
* package `Gnatls` for command LS or LIST (invoking `gnatls`)
* package `Linker` for command LINK (invoking `gnatlink`)
Package `Gnatls` has a unique attribute `Switches`,
a simple variable with a string list value. It contains switches
for the invocation of `gnatls`.
.. code-block:: gpr
project Proj1 is
package gnatls is
for Switches
use ("-a",
"-v");
end gnatls;
end Proj1;
All other packages have two attribute `Switches` and
`Default_Switches`.
`Switches` is an indexed attribute, indexed by the
source file name, that has a string list value: the switches to be
used when the tool corresponding to the package is invoked for the specific
source file.
`Default_Switches` is an attribute,
indexed by the programming language that has a string list value.
`Default_Switches ("Ada")` contains the
switches for the invocation of the tool corresponding
to the package, except if a specific `Switches` attribute
is specified for the source file.
.. code-block:: gpr
project Proj is
for Source_Dirs use ("");
package gnatls is
for Switches use
("-a",
"-v");
end gnatls;
package Compiler is
for Default_Switches ("Ada")
use ("-gnatv",
"-gnatwa");
end Binder;
package Binder is
for Default_Switches ("Ada")
use ("-C",
"-e");
end Binder;
package Linker is
for Default_Switches ("Ada")
use ("-C");
for Switches ("main.adb")
use ("-C",
"-v",
"-v");
end Linker;
package Finder is
for Default_Switches ("Ada")
use ("-a",
"-f");
end Finder;
package Cross_Reference is
for Default_Switches ("Ada")
use ("-a",
"-f",
"-d",
"-u");
end Cross_Reference;
end Proj;
With the above project file, commands such as
::
$ gnat comp -Pproj main
$ gnat ls -Pproj main
$ gnat xref -Pproj main
$ gnat bind -Pproj main.ali
$ gnat link -Pproj main.ali
will set up the environment properly and invoke the tool with the switches
found in the package corresponding to the tool:
`Default_Switches ("Ada")` for all tools,
except `Switches ("main.adb")`
for `gnatlink`.
.. only:: PRO or GPL
It is also possible to invoke some of the tools,
(`gnatcheck`,
`gnatmetric`,
and `gnatpp`)
on a set of project units thanks to the combination of the switches
*-P*, *-U* and possibly the main unit when one is interested
in its closure. For instance,
::
$ gnat metric -Pproj
will compute the metrics for all the immediate units of project `proj`.
::
$ gnat metric -Pproj -U
will compute the metrics for all the units of the closure of projects
rooted at `proj`.
::
$ gnat metric -Pproj -U main_unit
will compute the metrics for the closure of units rooted at
`main_unit`. This last possibility relies implicitly
on *gnatbind*'s option *-R*. But if the argument files for the
tool invoked by the *gnat* driver are explicitly specified
either directly or through the tool *-files* option, then the tool
is called only for these explicitly specified files.
"""Alternate Ada and Project Files parsers for Sphinx/Rest"""
import re
from pygments.lexer import RegexLexer, bygroups
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
Number, Punctuation
def get_lexer_tokens(tag_highlighting=False, project_support=False):
"""Return the tokens needed for RegexLexer
:param tag_highlighting: if True we support tag highlighting. See
AdaLexerWithTags documentation
:type tag_highlighting: bool
:param project_support: if True support additional keywors associated
with project files.
:type project_support: bool
:return: a dictionary following the structure required by RegexLexer
:rtype: dict
"""
if project_support:
project_pattern = r'project\s+|'
project_pattern2 = r'project|'
else:
project_pattern = r''
project_pattern2 = r''
result = {
'root': [
# Comments
(r'--.*$', Comment),
# Character literal
(r"'.'", String.Char),
# Strings
(r'"[^"]*"', String),
# Numeric
# Based literal
(r'[0-9][0-9_]*#[0-9a-f][0-9a-f_]*#(E[\+-]?[0-9][0-9_]*)?',
Number.Integer),
(r'[0-9][0-9_]*#[0-9a-f][0-9a-f_]*'
r'\.[0-9a-f][0-9a-f_]*#(E[\+-]?[0-9][0-9_]*)?', Number.Float),
# Decimal literal
(r'[0-9][0-9_]*\.[0-9][0-9_](E[\+-]?[0-9][0-9_]*)?', Number.Float),
(r'[0-9][0-9_]*(E[\+-]?[0-9][0-9_]*)?', Number.Integer),
# Match use and with statements
# The first part of the pattern is be sure we don't match
# for/use constructs.
(r'(\n\s*|;\s*)(with|use)(\s+[\w\.]+)',
bygroups(Punctuation, Keyword.Reserved, Name.Namespace)),
# Match procedure, package and function declarations
(r'end\s+(if|loop|record)', Keyword),
(r'(package(?:\s+body)?\s+|' + project_pattern +
r'function\s+|end\s+|procedure\s+)([\w\.]+)',
bygroups(Keyword, Name.Function)),
# Ada 2012 standard attributes, GNAT specific ones and
# Spark 2014 ones ('Update and 'Loop_Entry)
# (reversed order to avoid having for
# example Max before Max_Alignment_For_Allocation).
(r'\'(Write|Width|Wide_Width|Wide_Wide_Width|Wide_Wide_Value|'
r'Wide_Wide_Image|Wide_Value|Wide_Image|Word_Size|Wchar_T_Size|'
r'Version|Value_Size|Value|Valid_Scalars|VADS_Size|Valid|Val|'
r'Update|Unrestricted_Access|Universal_Literal_String|'
r'Unconstrained_Array|Unchecked_Access|Unbiased_Rounding|'
r'UET_Address|Truncation|Type_Class|To_Address|Tick|Terminated|'
r'Target_Name|Tag|System_Allocator_Alignment|Succ|Stub_Type|'
r'Stream_Size|Storage_Unit|Storage_Size|Storage_Pool|Small|Size|'
r'Simple_Storage_Pool|Signed_Zeros|Scaling|Scale|'
r'Scalar_Storage_Order|Safe_Last|Safe_Large|Safe_First|'
r'Safe_Emax|Rounding|Round|Result|Remainder|Ref|Read|'
r'Range_Length|Range|Priority|Pred|'
r'Position|Pos|Pool_Address|Passed_By_Reference|Partition_Id|'
r'Overlaps_Storage|Output|Old|Object_Size|Null_Parameter|Modulus|'
r'Model_Small|Model_Mantissa|Model_Epsilon|Model_Emin|Model|Mod|'
r'Min|Mechanism_Code|Maximum_Alignment|'
r'Max_Size_In_Storage_Elements|Max_Priority|'
r'Max_Interrupt_Priority|Max_Alignment_For_Allocation|'
r'Max|Mantissa|Machine_Size|Machine_Rounds|Machine_Rounding|'
r'Machine_Radix|Machine_Overflows|Machine_Mantissa|Machine_Emin|'
r'Machine_Emax|Machine|Loop_Entry|Length|Length|Leading_Part|'
r'Last_Valid|Last_Bit|Last|Large|Invalid_Value|Integer_Value|'
r'Input|Image|Img|Identity|Has_Same_Storage|Has_Discriminants|'
r'Has_Access_Values|Fraction|Fore|Floor|Fixed_Value|First_Valid|'
r'First_Bit|First|External_Tag|Exponent|Epsilon|Enum_Val|'
r'Enum_Rep|Enabled|Emax|Elaborated|Elab_Subp_Body|Elab_Spec|'
r'Elab_Body|Descriptor_Size|Digits|Denorm|Delta|Definite|'
r'Default_Bit_Order|Count|Copy_Sign|Constrained|'
r'Compose|Component_Size|Compiler_Version|Code_Address|Class|'
r'Ceiling|Caller|Callable|Body_Version|Bit_Order|Bit_Position|'
r'Bit|Base|Asm_Output|Asm_Input|Alignment|Aft|Adjacent|'
r'Address_Size|Address|Access|Abort_Signal|AST_Entry)',
Name.Attribute),
# All Ada2012 reserved words
(r'(abort|abstract|abs|accept|access|aliased|all|and|array|at|'
r'begin|body|case|constant|declare|delay|delta|digits|do|'
r'else|elsif|end|entry|exception|exit|for|function|generic|goto|'
r'if|interface|in|is|limited|loop|mod|new|not|null|'
r'of|or|others|out|overriding|' + project_pattern2 +
r'package|pragma|private|procedure|protected|'
r'raise|range|record|rem|renames|requeue|return|reverse|'
r'select|separate|some|subtype|synchronized|'
r'tagged|task|terminate|then|type|until|use|when|while|with|xor'
r')([\s;,])',
bygroups(Keyword.Reserved, Punctuation)),
# Two characters operators
(r'=>|\.\.|\*\*|:=|/=|>=|<=|<<|>>|<>', Operator),
# One character operators
(r'&|\'|\(|\)|\*|\+|-|\.|/|:|<|=|>|\|', Operator),
(r',|;', Punctuation),
# Spaces
(r'\s+', Text),
# Builtin values
(r'False|True', Keyword.Constant),
# Identifiers
(r'[\w\.]+', Name)], }
# Insert tag highlighting before identifiers
if tag_highlighting:
result['root'].insert(-1, (r'\[[\w ]*\]', Name.Tag))
return result
class AdaLexer(RegexLexer):
"""Alternate Pygments lexer for Ada source code and project files
The default pygments lexer always fails causing disabling of syntax
highlighting in Sphinx. This lexer is simpler but safer.
In order to use this lexer in your Sphinx project add the following
code at the end of your conf.py
.. code-block:: python
import gnatpython.ada_pygments
def setup(app):
app.add_lexer('ada', gnatpython.ada_pygments.AdaLexer())
"""
name = 'Ada'
aliases = ['ada', 'ada83', 'ada95', 'ada2005', 'ada2012']
filenames = ['*.adb', '*.ads', '*.ada']
mimetypes = ['text/x-ada']
flags = re.MULTILINE | re.I # Ignore case
tokens = get_lexer_tokens()
class TaggedAdaLexer(AdaLexer):
"""Alternate Pygments lexer for Ada source code with tags
A tag is a string of the form::
[MY STRING]
Only alphanumerical characters and spaces are considered inside the
brackets.
"""
name = 'TaggedAda'
aliases = ['tagged_ada']
tokens = get_lexer_tokens(True)
class GNATProjectLexer(RegexLexer):
"""Pygment lexer for project files
This is the same as the AdaLexer but with support of ``project``
keyword.
"""
name = 'GPR'
aliases = ['gpr']
filenames = ['*.gpr']
mimetypes = ['text/x-gpr']
flags = re.MULTILINE | re.I # Ignore case
tokens = get_lexer_tokens(project_support=True)
# -*- coding: utf-8 -*-
#
# GNAT build configuration file
import sys
import os
import time
import re
sys.path.append('.')
import ada_pygments
import latex_elements
# Some configuration values for the various documentation handled by
# this conf.py
DOCS = {
'gnat_rm': {
'title': u'GNAT Reference Manual'},
'gnat_ugn': {
'title': u'GNAT User\'s Guide for Native Platforms'}}
# Then retrieve the source directory
root_source_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
gnatvsn_spec = os.path.join(root_source_dir, '..', 'gnatvsn.ads')
basever = os.path.join(root_source_dir, '..', '..', 'BASE-VER')
texi_fsf = True # Set to False when FSF doc is switched to sphinx by default
with open(gnatvsn_spec, 'rb') as fd:
gnatvsn_content = fd.read()
def get_copyright():
return u'2008-%s, Free Software Foundation' % time.strftime('%Y')
def get_gnat_version():
m = re.search(r'Gnat_Static_Version_String : ' +
r'constant String := "([^\(\)]+)\(.*\)?";',
gnatvsn_content)
if m:
return m.group(1).strip()
else:
if texi_fsf and os.path.exists(basever):
return ''
try:
with open(basever, 'rb') as fd:
return fd.read()
except:
pass
print 'cannot find GNAT version in gnatvsn.ads or in ' + basever
sys.exit(1)
def get_gnat_build_type():
m = re.search(r'Build_Type : constant Gnat_Build_Type := (.+);',
gnatvsn_content)
if m:
return {'Gnatpro': 'PRO',
'FSF': 'FSF',
'GPL': 'GPL'}[m.group(1).strip()]
else:
print 'cannot compute GNAT build type'
sys.exit(1)
# First retrieve the name of the documentation we are building
doc_name = os.environ.get('DOC_NAME', None)
if doc_name is None:
print 'DOC_NAME environment variable should be set'
sys.exit(1)
if doc_name not in DOCS:
print '%s is not a valid documentation name' % doc_name
sys.exit(1)
# Exclude sources that are not part of the current documentation
exclude_patterns = []
for d in os.listdir(root_source_dir):
if d not in ('share', doc_name, doc_name + '.rst'):
exclude_patterns.append(d)
print 'ignoring %s' % d
if doc_name == 'gnat_rm':
exclude_patterns.append('share/gnat_project_manager.rst')
print 'ignoring share/gnat_project_manager.rst'
extensions = []
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = doc_name
# General information about the project.
project = DOCS[doc_name]['title']
copyright = get_copyright()
version = get_gnat_version()
release = get_gnat_version()
pygments_style = 'sphinx'
tags.add(get_gnat_build_type())
html_theme = 'sphinxdoc'
if os.path.isfile('adacore_transparent.png'):
html_logo = 'adacore_transparent.png'
if os.path.isfile('favicon.ico'):
html_favicon = 'favicon.ico'
html_static_path = ['_static']
latex_elements = {
'preamble': latex_elements.TOC_DEPTH +
latex_elements.PAGE_BLANK +
latex_elements.TOC_CMD +
latex_elements.LATEX_HYPHEN +
latex_elements.doc_settings(DOCS[doc_name]['title'],
get_gnat_version()),
'tableofcontents': latex_elements.TOC}
latex_documents = [
(master_doc, '%s.tex' % doc_name, project, u'AdaCore', 'manual')]
texinfo_documents = [
(master_doc, doc_name, project,
u'AdaCore', doc_name, doc_name, '')]
def setup(app):
app.add_lexer('ada', ada_pygments.AdaLexer())
app.add_lexer('gpr', ada_pygments.GNATProjectLexer())
.. _gnu_fdl:
******************************
GNU Free Documentation License
******************************
Version 1.3, 3 November 2008
Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc
http://fsf.org/
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
**Preamble**
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.
**1. APPLICABILITY AND DEFINITIONS**
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The **Document**, below,
refers to any such manual or work. Any member of the public is a
licensee, and is addressed as "**you**". You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
A "**Modified Version**" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "**Secondary Section**" is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject. (Thus, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The "**Invariant Sections**" are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
The "**Cover Texts**" are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "**Transparent**" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
of text. A copy that is not "Transparent" is called **Opaque**.
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML, PostScript or PDF designed for human modification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by
proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "**Title Page**" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, "Title Page" means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.
The "**publisher**" means any person or entity that distributes
copies of the Document to the public.
A section "**Entitled XYZ**" means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
specific section name mentioned below, such as "**Acknowledgements**",
"**Dedications**", "**Endorsements**", or "**History**".)
To "**Preserve the Title**"
of such a section when you modify the Document means that it remains a
section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this
License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has
no effect on the meaning of this License.
**2. VERBATIM COPYING**
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.
**3. COPYING IN QUANTITY**
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a computer-network location from which the general network-using
public has access to download using public-standard network protocols
a complete Transparent copy of the Document, free of added material.
If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure
that this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that
edition to the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.
**4. MODIFICATIONS**
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the "History" section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section all
the substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements"
or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties---for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.
**5. COMBINING DOCUMENTS**
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History"
in the various original documents, forming one section Entitled
"History"; likewise combine any sections Entitled "Acknowledgements",
and any sections Entitled "Dedications". You must delete all sections
Entitled "Endorsements".
**6. COLLECTIONS OF DOCUMENTS**
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.
**7. AGGREGATION WITH INDEPENDENT WORKS**
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, is called an "aggregate" if the copyright
resulting from the compilation is not used to limit the legal rights
of the compilation's users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
the entire aggregate, the Document's Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
aggregate.
**8. TRANSLATION**
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also include
the original English version of this License and the original versions
of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
**9. TERMINATION**
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void, and
will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, receipt of a copy of some or all of the same material does
not give you any rights to use it.
**10. FUTURE REVISIONS OF THIS LICENSE**
The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
License can be used, that proxy's public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.
**11. RELICENSING**
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
"Massive Multiauthor Collaboration" (or "MMC") contained in the
site means any set of copyrightable works thus published on the MMC
site.
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
"Incorporate" means to publish or republish a Document, in whole or
in part, as part of another Document.
An MMC is "eligible for relicensing" if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole
or in part into the MMC, (1) had no cover texts or invariant sections,
and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site
under CC-BY-SA on the same site at any time before August 1, 2009,
provided the MMC is eligible for relicensing.
**ADDENDUM: How to use this License for your documents**
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
Copyright © YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the "with ... Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.
# define some latex elements to be used for PDF output
PAGE_BLANK = r'''
\makeatletter
\def\cleartooddpage{%%
\cleardoublepage%%
}
\def\cleardoublepage{%%
\clearpage%%
\if@twoside%%
\ifodd\c@page%%
%% nothing to do
\else%%
\hbox{}%%
\thispagestyle{plain}%%
\vspace*{\fill}%%
\begin{center}%%
\textbf{\em This page is intentionally left blank.}%%
\end{center}%%
\vspace{\fill}%%
\newpage%%
\if@twocolumn%%
\hbox{}%%
\newpage%%
\fi%%
\fi%%
\fi%%
}
\makeatother
'''
TOC_DEPTH = r'''
\pagenumbering{arabic}
\setcounter{tocdepth}{3}
'''
TOC_CMD = r'''
\makeatletter
\def\tableofcontents{%%
\pagestyle{plain}%%
\chapter*{\contentsname}%%
\@mkboth{\MakeUppercase{\contentsname}}%%
{\MakeUppercase{\contentsname}}%%
\@starttoc{toc}%%
}
\makeatother
'''
TOC = r'''
\cleardoublepage
\tableofcontents
\cleardoublepage\pagestyle{plain}
'''
LATEX_HYPHEN = r'''
\hyphenpenalty=5000
\tolerance=1000
'''
def doc_settings(full_document_name, version):
return '\n'.join([
r'\newcommand*{\GNATFullDocumentName}[0]{' + full_document_name + r'}',
r'\newcommand*{\GNATVersion}[0]{' + version + r'}'])
%
% sphinx.sty
%
% Adapted from the old python.sty, mostly written by Fred Drake,
% by Georg Brandl.
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{sphinx}[2010/01/15 LaTeX package (Sphinx markup)]
\@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}}
\RequirePackage{textcomp}
\RequirePackage{fancybox}
\RequirePackage{titlesec}
\RequirePackage{tabulary}
\RequirePackage{amsmath} % for \text
\RequirePackage{makeidx}
\RequirePackage{framed}
\RequirePackage{ifthen}
\RequirePackage{color}
% For highlighted code.
\RequirePackage{fancyvrb}
% For table captions.
\RequirePackage{threeparttable}
% Handle footnotes in tables.
\RequirePackage{footnote}
\makesavenoteenv{tabulary}
% For floating figures in the text.
\RequirePackage{wrapfig}
% Separate paragraphs by space by default.
\RequirePackage{parskip}
\RequirePackage{lastpage}
% Redefine these colors to your liking in the preamble.
\definecolor{TitleColor}{rgb}{0.126,0.263,0.361}
\definecolor{InnerLinkColor}{rgb}{0.208,0.374,0.486}
\definecolor{OuterLinkColor}{rgb}{0.216,0.439,0.388}
% Required to preserve indentation settings in minipage constructs
% (otherwise parskip is set to 0 by default. minipagerestore is called
% each time we enter a minipage environment)
\newcommand{\@minipagerestore}{\setlength{\parskip}{\medskipamount}}
% Redefine these colors to something not white if you want to have colored
% background and border for code examples.
\definecolor{VerbatimColor}{rgb}{1,1,1}
\definecolor{VerbatimBorderColor}{rgb}{1,1,1}
% Uncomment these two lines to ignore the paper size and make the page
% size more like a typical published manual.
%\renewcommand{\paperheight}{9in}
%\renewcommand{\paperwidth}{8.5in} % typical squarish manual
%\renewcommand{\paperwidth}{7in} % O'Reilly ``Programmming Python''
% use pdfoutput for pTeX and dvipdfmx
\ifx\kanjiskip\undefined\else
\ifx\Gin@driver{dvipdfmx.def}\undefined\else
\newcount\pdfoutput\pdfoutput=0
\fi
\fi
% For graphicx, check if we are compiling under latex or pdflatex.
\ifx\pdftexversion\undefined
\usepackage{graphicx}
\else
\usepackage[pdftex]{graphicx}
\fi
% for PDF output, use colors and maximal compression
\newif\ifsphinxpdfoutput\sphinxpdfoutputfalse
\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
\let\py@NormalColor\relax
\let\py@TitleColor\relax
\else
\sphinxpdfoutputtrue
\input{pdfcolor}
\def\py@NormalColor{\color[rgb]{0.0,0.0,0.0}}
\def\py@TitleColor{\color{TitleColor}}
\pdfcompresslevel=9
\fi\fi
% XeLaTeX can do colors, too
\ifx\XeTeXrevision\undefined\else
\def\py@NormalColor{\color[rgb]{0.0,0.0,0.0}}
\def\py@TitleColor{\color{TitleColor}}
\fi
% Increase printable page size (copied from fullpage.sty)
\topmargin 0pt
\advance \topmargin by -\headheight
\advance \topmargin by -\headsep
% attempt to work a little better for A4 users
\textheight \paperheight
\advance\textheight by -2in
\oddsidemargin 0pt
\evensidemargin 0pt
%\evensidemargin -.25in % for ``manual size'' documents
\marginparwidth 0.5in
\textwidth \paperwidth
\advance\textwidth by -2in
% Style parameters and macros used by most documents here
\raggedbottom
\sloppy
\hbadness = 5000 % don't print trivial gripes
\pagestyle{empty} % start this way
\renewcommand{\maketitle}{%
\begin{titlepage}%
\let\footnotesize\small
\let\footnoterule\relax
\rule{\textwidth}{1pt}%
\ifsphinxpdfoutput
\begingroup
% These \defs are required to deal with multi-line authors; it
% changes \\ to ', ' (comma-space), making it pass muster for
% generating document info in the PDF file.
\def\\{, }
\def\and{and }
\pdfinfo{
/Author (\@author)
/Title (\@title)
}
\endgroup
\fi
\begin{flushright}%
\sphinxlogo%
{\rm\Huge \@title \par}%
{\em\LARGE\py@HeaderFamily \py@release\releaseinfo \par}
\vfill
{\LARGE\py@HeaderFamily
\par}
\vfill\vfill
{\large
\@date \par
\vfill
\py@authoraddress \par
}%
\end{flushright}%\par
\@thanks
\end{titlepage}%
\cleardoublepage%
\setcounter{footnote}{0}%
\let\thanks\relax\let\maketitle\relax
}
% Use this to set the font family for headers and other decor:
\newcommand{\py@HeaderFamily}{\sffamily\bfseries}
% Redefine the 'normal' header/footer style when using "fancyhdr" package:
\@ifundefined{fancyhf}{}{
% Use \pagestyle{normal} as the primary pagestyle for text.
\fancypagestyle{normal}{
\fancyhf{}
\fancyfoot[LE,RO]{{\py@HeaderFamily\thepage\ of \pageref*{LastPage}}}
\fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}}
\fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}}
\fancyhead[LE,RO]{{\py@HeaderFamily \@title, \py@release}}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
% define chaptermark with \@chappos when \@chappos is available for Japanese
\ifx\@chappos\undefined\else
\def\chaptermark##1{\markboth{\@chapapp\space\thechapter\space\@chappos\space ##1}{}}
\fi
}
% Update the plain style so we get the page number & footer line,
% but not a chapter or section title. This is to keep the first
% page of a chapter and the blank page between chapters `clean.'
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[LE,RO]{{\py@HeaderFamily\thepage\ of \pageref*{LastPage}}}
\fancyfoot[LO,RE]{{\py@HeaderFamily \GNATFullDocumentName}}
\fancyhead[LE,RO]{{\py@HeaderFamily \@title\ \GNATVersion}}
\renewcommand{\headrulewidth}{0.0pt}
\renewcommand{\footrulewidth}{0.4pt}
}
}
% Some custom font markup commands.
%
\newcommand{\strong}[1]{{\textbf{#1}}}
\newcommand{\code}[1]{\texttt{#1}}
\newcommand{\bfcode}[1]{\code{\bfseries#1}}
\newcommand{\email}[1]{\textsf{#1}}
% Redefine the Verbatim environment to allow border and background colors.
% The original environment is still used for verbatims within tables.
\let\OriginalVerbatim=\Verbatim
\let\endOriginalVerbatim=\endVerbatim
% Play with vspace to be able to keep the indentation.
\newlength\distancetoright
\def\mycolorbox#1{%
\setlength\distancetoright{\linewidth}%
\advance\distancetoright -\@totalleftmargin %
\fcolorbox{VerbatimBorderColor}{VerbatimColor}{%
\begin{minipage}{\distancetoright}%
#1
\end{minipage}%
}%
}
\def\FrameCommand{\mycolorbox}
\renewcommand{\Verbatim}[1][1]{%
% list starts new par, but we don't want it to be set apart vertically
\bgroup\parskip=0pt%
\smallskip%
% The list environement is needed to control perfectly the vertical
% space.
\list{}{%
\setlength\parskip{0pt}%
\setlength\itemsep{0ex}%
\setlength\topsep{0ex}%
\setlength\partopsep{0pt}%
\setlength\leftmargin{0pt}%
}%
\item\MakeFramed {\FrameRestore}%
\small%
\OriginalVerbatim[#1]%
}
\renewcommand{\endVerbatim}{%
\endOriginalVerbatim%
\endMakeFramed%
\endlist%
% close group to restore \parskip
\egroup%
}
% \moduleauthor{name}{email}
\newcommand{\moduleauthor}[2]{}
% \sectionauthor{name}{email}
\newcommand{\sectionauthor}[2]{}
% Augment the sectioning commands used to get our own font family in place,
% and reset some internal data items:
\titleformat{\section}{\Large\py@HeaderFamily}%
{\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor}
\titleformat{\subsection}{\large\py@HeaderFamily}%
{\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
\titleformat{\subsubsection}{\py@HeaderFamily}%
{\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
\titleformat{\paragraph}{\small\py@HeaderFamily}%
{\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor}
% {fulllineitems} is the main environment for object descriptions.
%
\newcommand{\py@itemnewline}[1]{%
\@tempdima\linewidth%
\advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}%
}
\newenvironment{fulllineitems}{
\begin{list}{}{\labelwidth \leftmargin \labelsep 0pt
\rightmargin 0pt \topsep -\parskip \partopsep \parskip
\itemsep -\parsep
\let\makelabel=\py@itemnewline}
}{\end{list}}
% \optional is used for ``[, arg]``, i.e. desc_optional nodes.
\newcommand{\optional}[1]{%
{\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
\newlength{\py@argswidth}
\newcommand{\py@sigparams}[2]{%
\parbox[t]{\py@argswidth}{#1\code{)}#2}}
\newcommand{\pysigline}[1]{\item[#1]\nopagebreak}
\newcommand{\pysiglinewithargsret}[3]{%
\settowidth{\py@argswidth}{#1\code{(}}%
\addtolength{\py@argswidth}{-2\py@argswidth}%
\addtolength{\py@argswidth}{\linewidth}%
\item[#1\code{(}\py@sigparams{#2}{#3}]}
% Production lists
%
\newenvironment{productionlist}{
% \def\optional##1{{\Large[}##1{\Large]}}
\def\production##1##2{\\\code{##1}&::=&\code{##2}}
\def\productioncont##1{\\& &\code{##1}}
\parindent=2em
\indent
\begin{tabular}{lcl}
}{%
\end{tabular}
}
% Notices / Admonitions
%
\newlength{\py@noticelength}
\newcommand{\py@heavybox}{
\setlength{\fboxrule}{1pt}
\setlength{\fboxsep}{6pt}
\setlength{\py@noticelength}{\linewidth}
\addtolength{\py@noticelength}{-2\fboxsep}
\addtolength{\py@noticelength}{-2\fboxrule}
%\setlength{\shadowsize}{3pt}
\noindent\Sbox
\minipage{\py@noticelength}
}
\newcommand{\py@endheavybox}{
\endminipage
\endSbox
\fbox{\TheSbox}
}
\newcommand{\py@lightbox}{{%
\setlength\parskip{0pt}\par
\noindent\rule[0ex]{\linewidth}{0.5pt}%
\par\noindent\vspace{-0.5ex}%
}}
\newcommand{\py@endlightbox}{{%
\setlength{\parskip}{0pt}%
\par\noindent\rule[0.5ex]{\linewidth}{0.5pt}%
\par\vspace{-0.5ex}%
}}
% Some are quite plain:
\newcommand{\py@noticestart@note}{\py@lightbox}
\newcommand{\py@noticeend@note}{\py@endlightbox}
\newcommand{\py@noticestart@hint}{\py@lightbox}
\newcommand{\py@noticeend@hint}{\py@endlightbox}
\newcommand{\py@noticestart@important}{\py@lightbox}
\newcommand{\py@noticeend@important}{\py@endlightbox}
\newcommand{\py@noticestart@tip}{\py@lightbox}
\newcommand{\py@noticeend@tip}{\py@endlightbox}
% Others gets more visible distinction:
\newcommand{\py@noticestart@warning}{\py@heavybox}
\newcommand{\py@noticeend@warning}{\py@endheavybox}
\newcommand{\py@noticestart@caution}{\py@heavybox}
\newcommand{\py@noticeend@caution}{\py@endheavybox}
\newcommand{\py@noticestart@attention}{\py@heavybox}
\newcommand{\py@noticeend@attention}{\py@endheavybox}
\newcommand{\py@noticestart@danger}{\py@heavybox}
\newcommand{\py@noticeend@danger}{\py@endheavybox}
\newcommand{\py@noticestart@error}{\py@heavybox}
\newcommand{\py@noticeend@error}{\py@endheavybox}
\newenvironment{notice}[2]{
\def\py@noticetype{#1}
\csname py@noticestart@#1\endcsname
\strong{#2}
}{\csname py@noticeend@\py@noticetype\endcsname}
% Allow the release number to be specified independently of the
% \date{}. This allows the date to reflect the document's date and
% release to specify the release that is documented.
%
\newcommand{\py@release}{}
\newcommand{\version}{}
\newcommand{\shortversion}{}
\newcommand{\releaseinfo}{}
\newcommand{\releasename}{GNAT}
\newcommand{\release}[1]{%
\renewcommand{\py@release}{\releasename\space\version}%
\renewcommand{\version}{#1}}
\newcommand{\setshortversion}[1]{%
\renewcommand{\shortversion}{#1}}
\newcommand{\setreleaseinfo}[1]{%
\renewcommand{\releaseinfo}{#1}}
% Allow specification of the author's address separately from the
% author's name. This can be used to format them differently, which
% is a good thing.
%
\newcommand{\py@authoraddress}{}
\newcommand{\authoraddress}[1]{\renewcommand{\py@authoraddress}{#1}}
% This sets up the fancy chapter headings that make the documents look
% at least a little better than the usual LaTeX output.
%
\@ifundefined{ChTitleVar}{}{
\ChNameVar{\raggedleft\normalsize\py@HeaderFamily}
\ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily}
\ChTitleVar{\raggedleft \textrm{\Huge\py@HeaderFamily}}
% This creates chapter heads without the leading \vspace*{}:
\def\@makechapterhead#1{%
{\parindent \z@ \raggedright \normalfont
\ifnum \c@secnumdepth >\m@ne
\DOCH
\fi
\interlinepenalty\@M
\DOTI{#1}
}
}
}
% Redefine description environment so that it is usable inside fulllineitems.
%
\renewcommand{\description}{%
\list{}{\labelwidth\z@%
\itemindent-\leftmargin%
\labelsep5pt%
\let\makelabel=\descriptionlabel}}
% Definition lists; requested by AMK for HOWTO documents. Probably useful
% elsewhere as well, so keep in in the general style support.
%
\newenvironment{definitions}{%
\begin{description}%
\def\term##1{\item[##1]\mbox{}\\*[0mm]}
}{%
\end{description}%
}
% Tell TeX about pathological hyphenation cases:
\hyphenation{Base-HTTP-Re-quest-Hand-ler}
% The following is stuff copied from docutils' latex writer.
%
\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
\newenvironment{optionlist}[1]
{\begin{list}{}
{\setlength{\labelwidth}{#1}
\setlength{\rightmargin}{1cm}
\setlength{\leftmargin}{\rightmargin}
\addtolength{\leftmargin}{\labelwidth}
\addtolength{\leftmargin}{\labelsep}
\renewcommand{\makelabel}{\optionlistlabel}}
}{\end{list}}
\newlength{\lineblockindentation}
\setlength{\lineblockindentation}{2.5em}
\newenvironment{lineblock}[1]
{\begin{list}{}
{\setlength{\partopsep}{\parskip}
\addtolength{\partopsep}{\baselineskip}
\topsep0pt\itemsep0.15\baselineskip\parsep0pt
\leftmargin#1}
\raggedright}
{\end{list}}
% Redefine includgraphics for avoiding images larger than the screen size
% If the size is not specified.
\let\py@Oldincludegraphics\includegraphics
\newbox\image@box%
\newdimen\image@width%
\renewcommand\includegraphics[2][\@empty]{%
\ifx#1\@empty%
\setbox\image@box=\hbox{\py@Oldincludegraphics{#2}}%
\image@width\wd\image@box%
\ifdim \image@width>\linewidth%
\setbox\image@box=\hbox{\py@Oldincludegraphics[width=\linewidth]{#2}}%
\box\image@box%
\else%
\py@Oldincludegraphics{#2}%
\fi%
\else%
\py@Oldincludegraphics[#1]{#2}%
\fi%
}
% to make pdf with correct encoded bookmarks in Japanese
% this should precede the hyperref package
\ifx\kanjiskip\undefined\else
\usepackage{atbegshi}
\ifx\ucs\undefined
\ifnum 42146=\euc"A4A2
\AtBeginShipoutFirst{\special{pdf:tounicode EUC-UCS2}}
\else
\AtBeginShipoutFirst{\special{pdf:tounicode 90ms-RKSJ-UCS2}}
\fi
\else
\AtBeginShipoutFirst{\special{pdf:tounicode UTF8-UCS2}}
\fi
\fi
% Include hyperref last.
\RequirePackage[colorlinks,breaklinks,destlabel,
linkcolor=InnerLinkColor,filecolor=OuterLinkColor,
menucolor=OuterLinkColor,urlcolor=OuterLinkColor,
citecolor=InnerLinkColor]{hyperref}
% Fix anchor placement for figures with captions.
% (Note: we don't use a package option here; instead, we give an explicit
% \capstart for figures that actually have a caption.)
\RequirePackage{hypcap}
% From docutils.writers.latex2e
\providecommand{\DUspan}[2]{%
{% group ("span") to limit the scope of styling commands
\@for\node@class@name:=#1\do{%
\ifcsname docutilsrole\node@class@name\endcsname%
\csname docutilsrole\node@class@name\endcsname%
\fi%
}%
{#2}% node content
}% close "span"
}
\providecommand*{\DUprovidelength}[2]{
\ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{}
}
\DUprovidelength{\DUlineblockindent}{2.5em}
\ifthenelse{\isundefined{\DUlineblock}}{
\newenvironment{DUlineblock}[1]{%
\list{}{\setlength{\partopsep}{\parskip}
\addtolength{\partopsep}{\baselineskip}
\setlength{\topsep}{0pt}
\setlength{\itemsep}{0.15\baselineskip}
\setlength{\parsep}{0pt}
\setlength{\leftmargin}{#1}}
\raggedright
}
{\endlist}
}{}
% From footmisc.sty: allows footnotes in titles
\let\FN@sf@@footnote\footnote
\def\footnote{\ifx\protect\@typeset@protect
\expandafter\FN@sf@@footnote
\else
\expandafter\FN@sf@gobble@opt
\fi
}
\edef\FN@sf@gobble@opt{\noexpand\protect
\expandafter\noexpand\csname FN@sf@gobble@opt \endcsname}
\expandafter\def\csname FN@sf@gobble@opt \endcsname{%
\@ifnextchar[%]
\FN@sf@gobble@twobracket
\@gobble
}
\def\FN@sf@gobble@twobracket[#1]#2{}
% adjust the margins for footer,
% this works with the jsclasses only (Japanese standard document classes)
\ifx\@jsc@uplatextrue\undefined\else
\hypersetup{setpagesize=false}
\setlength\footskip{2\baselineskip}
\addtolength{\textheight}{-2\baselineskip}
\fi
% fix the double index and bibliography on the table of contents
% in jsclasses (Japanese standard document classes)
\ifx\@jsc@uplatextrue\undefined\else
\renewcommand{\theindex}{
\cleardoublepage
\phantomsection
\py@OldTheindex
}
\renewcommand{\thebibliography}[1]{
\cleardoublepage
\phantomsection
\py@OldThebibliography{1}
}
\fi
% do not use \@chappos in Appendix in pTeX
\ifx\kanjiskip\undefined\else
\renewcommand{\appendix}{\par
\setcounter{chapter}{0}
\setcounter{section}{0}
\gdef\@chapapp{\appendixname}
\gdef\@chappos{}
\gdef\thechapter{\@Alph\c@chapter}
}
\fi
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment