Skip to content

Commit 512f834

Browse files
authored
Merge pull request #1185 from gusthoff/content/advanced_ada/new_content/exceptions/classification_of_errors/20250217
Adding section on classification of errors
2 parents 237588d + e246f6a commit 512f834

File tree

2 files changed

+205
-11
lines changed

2 files changed

+205
-11
lines changed

content/courses/advanced-ada/parts/control_flow/exceptions.rst

Lines changed: 203 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,210 @@ Exceptions
33

44
.. include:: ../../../global.txt
55

6-
..
7-
TO BE DONE:
86

9-
Classification of Errors
10-
------------------------
7+
.. _Adv_Ada_Classification_Of_Errors:
118

12-
.. admonition:: In the Ada Reference Manual
9+
Classification of Errors
10+
------------------------
1311

14-
- :arm:`1.1.5 Classification of Errors <1-1-5>`
12+
When we talk about errors and erroneous behavior in Ada, we can classify them
13+
in one of the four categories:
1514

16-
.. todo::
15+
- compilation errors |mdash| i.e. errors that an Ada compiler must detect at
16+
compilation time;
17+
18+
- runtime errors |mdash| i.e. errors that are detected by an Ada-based
19+
application using checks at runtime;
20+
21+
- bounded errors;
22+
23+
- erroneous execution.
24+
25+
In this section, we discuss each of these categories.
26+
27+
.. admonition:: In the Ada Reference Manual
28+
29+
- :arm:`1.1.5 Classification of Errors <1-1-5>`
30+
31+
32+
.. _Adv_Ada_Compilation_Errors:
33+
34+
Compilation errors
35+
~~~~~~~~~~~~~~~~~~
36+
37+
In the category of compilation errors, the goal is to prevent compilers from
38+
accepting illegal programs. Here, any program that doesn't follow the rules
39+
described in the Ada Reference Manual is considered illegal. Those rules
40+
include not only simple syntax errors, but also more complicated semantic
41+
rules, such as the ones concerning
42+
:ref:`accessibility levels <Adv_Ada_Accessibility_Levels_Intro>` for access
43+
types.
44+
45+
Note that Ada |mdash| in contrast to many programming languages, which can be
46+
quite permissive |mdash| tries to prevent as many errors as possible at
47+
compilation time because of its focus on safety. However, even though a wide
48+
range of errors can be detected at compilation time, this doesn't mean that a
49+
legal Ada program is free of errors. Therefore, using methods such as static
50+
analysis or unit testing is important.
51+
52+
53+
.. _Adv_Ada_Runtime_Errors:
54+
55+
Runtime errors
56+
~~~~~~~~~~~~~~
57+
58+
When a rule cannot be verified at compilation time, a common strategy is to
59+
have the compiler insert runtime checks into the resulting application. We see
60+
details about these checks later on when we discuss
61+
:ref:`checks and exceptions <Adv_Ada_Checks_And_Exceptions>`.
62+
63+
A typical example is an :ref:`overflow check <Adv_Ada_Overflow_Check>`.
64+
Consider a calculation using variables: if this calculation leads to a result
65+
that isn't representable with the underlying data types, we cannot possibly
66+
store a value into a register or memory that can be considered correct |mdash|
67+
so we have to detect this situation. Unfortunately, because we're using
68+
variables, we obviously cannot verify the result of the calculation at
69+
compilation time, so we have to verify it at runtime.
70+
71+
As we've mentioned before, Ada strives for detecting as many erroneous
72+
conditions as possible, while other programming language would allow errors
73+
such as overflow errors to remain undetected |mdash| which would likely lead
74+
the application to misbehave. Those checks raise an exception if an erroneous
75+
condition is detected, so the programmer has the means |mdash| and the
76+
responsibility |mdash| to catch that exception and handle the situation
77+
properly (Note, however, that some of the runtime checks can be deactivated.
78+
We will discuss this topic later on.)
79+
80+
81+
.. _Adv_Ada_Bounded_Errors:
82+
83+
Bounded errors
84+
~~~~~~~~~~~~~~
85+
86+
For certain kinds of errors, the compiler might not be able to detect the error
87+
|mdash| neither at compilation time, nor with checks at runtime. Such errors
88+
are called bounded errors because their possible effects are *bounded*.
89+
In fact, the
90+
Ada Reference Manual describes each bounded error and its possible effects
91+
|mdash| one of those effects is raising the :ada:`Program_Error` exception.
92+
93+
Just as an example, consider the bounded error described in section
94+
:arm:`13.9.1 Data Validity <13-9-1>`, paragraphs 9:
95+
96+
If the representation of a scalar object does not represent a value of the
97+
object's subtype (perhaps because the object was not initialized), the
98+
object is said to have an invalid representation. It is a bounded error to
99+
evaluate the value of such an object. If the error is detected, either
100+
:ada:`Constraint_Error` or :ada:`Program_Error` is raised. Otherwise,
101+
execution continues using the invalid representation. The rules of the
102+
language outside this subclause assume that all objects have valid
103+
representations.
104+
105+
Let's see a code example:
106+
107+
.. code:: ada no_button project=Courses.Advanced_Ada.Control_Flow.Exceptions.Classification_Of_Errors.Data_Validity_Bounded_Error
108+
:class: ada-run
17109

18-
- (MENTION: bounded errors)
110+
with Ada.Text_IO; use Ada.Text_IO;
111+
112+
procedure Show_Bounded_Error is
113+
subtype Int_1_10 is
114+
Integer range 1 .. 10;
115+
116+
I1 : Int_1_10;
117+
I1_Overlay : Integer
118+
with Address => I1'Address,
119+
Import,
120+
Volatile;
121+
begin
122+
I1_Overlay := 0;
123+
-- ^^^^^^^^^^^
124+
-- We use this overlay to write an invalid
125+
-- value to I1.
126+
127+
Put_Line ("I1 = " & I1'Image);
128+
-- ^^^^^^^^
129+
-- Bounded error: value in
130+
-- I1 is out of range.
131+
132+
I1 := I1 + 1;
133+
-- ^^
134+
-- Bounded error: using value
135+
-- in operation that is out of
136+
-- range.
137+
138+
Put_Line ("I1 = " & I1'Image);
139+
end Show_Bounded_Error;
140+
141+
In this example, we simulate a missing initialization by using an overlay
142+
(:ada:`I1_Overlay`). As a consequence, :ada:`I1` has an invalid value that is
143+
out of the allowed range of the :ada:`Int_1_10` subtype. This situation causes
144+
two bounded errors:
145+
146+
- a bounded error when :ada:`I1` is evaluated in the call to :ada:`Image`; and
147+
148+
- a bounded error when the value of the right-sided :ada:`I1` is evaluated
149+
|mdash| in the increment :ada:`I1 := I1 + 1`.
150+
151+
.. admonition:: In the Ada Reference Manual
152+
153+
- :arm:`13.9.1 Data Validity <13-9-1>`
154+
155+
156+
.. _Adv_Ada_Erroneous_Execution:
157+
158+
Erroneous execution
159+
~~~~~~~~~~~~~~~~~~~
160+
161+
Erroneous execution is similar to bounded errors in the sense that having the
162+
compiler detect the erroneous condition at compilation time or at runtime isn't
163+
possible. However, unlike bounded errors, the effects are usually
164+
nondeterministic: a bound on possible effects is not described by the language.
165+
166+
Again, as an example of erroneous execution, consider the description from
167+
section :arm:`13.9.1 Data Validity <13-9-1>`, paragraph 12/3, which discusses
168+
the implications of using the :ada:`Unchecked_Conversion` function. Let's see a
169+
code example:
170+
171+
.. code:: ada no_button project=Courses.Advanced_Ada.Control_Flow.Exceptions.Classification_Of_Errors.Data_Validity_Erroneous_Execution
172+
:class: ada-run
173+
174+
with Ada.Text_IO; use Ada.Text_IO;
175+
with Ada.Unchecked_Conversion;
176+
177+
procedure Show_Erroneous_Execution is
178+
subtype Int_1_10 is
179+
Integer range 1 .. 10;
180+
181+
function To_Int_1_10 is new
182+
Ada.Unchecked_Conversion
183+
(Source => Integer,
184+
Target => Int_1_10);
185+
186+
I1 : Int_1_10 := To_Int_1_10 (0);
187+
-- ^^^^^^^^^^^^^^^
188+
-- Bounded error
189+
begin
190+
Put_Line ("I1 = " & I1'Image);
191+
192+
I1 := I1 + 1;
193+
-- ^^^^^^
194+
-- Erroneous execution: using value
195+
-- in operation that is out of range.
196+
197+
Put_Line ("I1 = " & I1'Image);
198+
end Show_Erroneous_Execution;
199+
200+
It is considered to be a bounded error to use the :ada:`To_Int_1_10` function
201+
(based on :ada:`Unchecked_Conversion`) with a value that is invalid for the
202+
target data type. However, if we use the invalid value of :ada:`I1` in an
203+
operation such as the :ada:`I1 := I1 + 1` assignment, this leads to erroneous
204+
execution, and the effects are unpredictable: they aren't described in the Ada
205+
Reference Manual, as they are nondeterministic.
206+
207+
.. admonition:: In the Ada Reference Manual
208+
209+
- :arm:`13.9.1 Data Validity <13-9-1>`
19210

20211

21212
Asserts
@@ -178,7 +369,7 @@ The following table presents all policies that we can set:
178369
a policy to :ada:`Disable` and :ada:`Suppressible`.
179370

180371
You can read more about them in the
181-
`GNAT Reference Manual <https://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Assertion_005fPolicy.html>`_.
372+
`GNAT Reference Manual <https://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Assertion_005fPolicy>`_.
182373

183374
You can specify multiple policies in a single call to :ada:`Assertion_Policy`.
184375
For example, you can activate all policies by writing:
@@ -204,7 +395,7 @@ For example, you can activate all policies by writing:
204395

205396
With GNAT, policies can be specified in multiple ways. In addition to calls
206397
to :ada:`Assertion_Policy`, you can use
207-
`configuration pragmas files <https://gcc.gnu.org/onlinedocs/gnat_ugn/The-Configuration-Pragmas-Files.html#The-Configuration-Pragmas-Files>`_.
398+
`configuration pragmas files <https://gcc.gnu.org/onlinedocs/gnat_ugn/The-Configuration-Pragmas-Files#The-Configuration-Pragmas-Files>`_.
208399
You can use these files to specify all pragmas that are relevant to your
209400
application, including :ada:`Assertion_Policy`. In addition, you can manage
210401
the granularity for those pragmas. For example, you can use a global
@@ -262,6 +453,8 @@ the call to :ada:`Assert` is not ignored.
262453
Complete section!
263454

264455

456+
.. _Adv_Ada_Checks_And_Exceptions:
457+
265458
Checks and exceptions
266459
---------------------
267460

content/courses/advanced-ada/parts/resource_management/controlled_types.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2107,7 +2107,8 @@ procedure is never called for object :ada:`A`.
21072107
Bounded errors of controlled types
21082108
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21092109

2110-
Bounded errors are an important topic when talking about exception and
2110+
:ref:`Bounded errors <Adv_Ada_Bounded_Errors>` are an important topic when
2111+
talking about exception and
21112112
controlled types. In general, if an exception is raised in the :ada:`Adjust` or
21122113
:ada:`Finalize` procedure, this is considered a bounded error. If the bounded
21132114
error is detected, the :ada:`Program_Error` exception is raised.

0 commit comments

Comments
 (0)