@@ -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
21212Asserts
@@ -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
183374You can specify multiple policies in a single call to :ada: `Assertion_Policy `.
184375For 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+
265458Checks and exceptions
266459---------------------
267460
0 commit comments