Program_Error
, possibly to
write a message to that effect, or to do nothing at all.Erroneousness is not a concept unique to Ada. The guidelines below describe or explain the specific instances of erroneousness defined in the Ada Language Reference Manual. Although Incorrect Order Dependencies is not, strictly speaking, a case of erroneous execution, the rationale for avoiding such dependencies is the same. Consequently, the guideline is included in this section.
Language Ref Manual references: 1.6 Classification of Errors
Unchecked_Conversion
only with the utmost care (Department of
Defense 1983, section 13.10.2).
Unchecked_Conversion
is in range.
Unchecked_Conversion
in package bodies.
------------------------------------------------------------------------ with Unchecked_Conversion; with Text_IO; procedure Test is type Color is (Red, Yellow, Blue); function Integer_To_Color is new Unchecked_Conversion (Source => Integer, Target => Color); A_Color : Color; List : array (Color) of Boolean; Data : Boolean; begin -- Test A_Color := Integer_To_Color(15); Data := List(A_Color); Text_IO.Put_Line(Color'Image(A_Color)); end Test; ------------------------------------------------------------------------ |
Language Ref Manual references: 4.6 Type Conversions, 7.3 Package Bodies, 13.10.2 Unchecked Type Conversions
Unchecked_Deallocation
in package bodies.
Unchecked_Deallocation
with caution have been
given in Guideline 5.4.3. When this feature is used, there is no checking that
there is only one access path to the storage being deallocated. Thus, any
other access paths are not made null
. Depending on such a check is erroneous.Language Ref Manual references: 3.8 Access Types, 13.10.1 Unchecked Storage Deallocation
------------------------------------------------------------------------ with Text_IO; procedure Outer is type Coordinates is record X : Integer := 0; Y : Integer := 0; end record; Outer_Point : Coordinates; package Integer_IO is new Text_IO.Integer_IO (Num => Integer); --------------------------------------------------------------------- procedure Inner (Inner_Point : in out Coordinates) is begin Inner_Point.X := 5; -- The following line causes the output of the program to -- depend on the parameter passing mechanism. Integer_IO.Put(Outer_Point.X); end Inner; --------------------------------------------------------------------- begin -- Outer Integer_IO.Put(Outer_Point.X); Inner (Outer_Point); Integer_IO.Put(Outer_Point.X); end Outer; ------------------------------------------------------------------------ |
0 0 5
If the parameter passing mechanism is by reference, the results are:
0 5 5
Language Ref Manual references: 3.6 Array Types, 3.7 Record Types, 6.2 Formal Parameter Modes, 6.4 Subprogram Calls, 13.9 Interface to Other Languages
Single_Address : constant ... Interrupt_Vector_Table : Hardware_Array; for Interrupt_Vector_Table use at Single_Address; |
Language Ref Manual references: 9.5 Entries, Entry Calls, and Accept Statements, 13.5 Address Clauses, 13.5.1 Interrupts
By minimizing the code which has exception checking removed, you increase the reliability of the program. There is a rule of thumb which suggests that 20 percent of the code is responsible for 80 percent of the CPU time. So once you have identified the code that actually needs exception checking removed, it is wise to isolate it in a block (with appropriate comments) and leave the surrounding code with exception checking in effect.
Language Ref Manual references: 11.7 Suppressing Checks, B Predefined Language Pragmas
------------------------------------------------------------------------ package Robot_Controller is ... function Sense return Position; ... end Robot_Controller; ------------------------------------------------------------------------ package body Robot_Controller is ... Goal : Position := Sense; -- This raises Program_Error ... --------------------------------------------------------------------- function Sense return Position is begin ... end Sense; --------------------------------------------------------------------- begin -- Robot_Controller Goal := Sense; -- The function has been elaborated. ... end Robot_Controller; ------------------------------------------------------------------------ |
Ensuring initialization does not imply initialization at the declaration. In
the example above, Goal must be initialized via a function call. This cannot
occur at the declaration, because the function Sense
has not yet been
elaborated, but can occur later as part of the sequence of statements of the
body of the enclosing package.
An unelaborated function called within a declaration (initialization) raises
the exception, Program_Error
, that must be handled outside of the unit
containing the declarations. This is true for any exception the function
raises even if it has been elaborated.
If an exception is raised by a function call in a declaration, it is not handled in that immediate scope. It is raised to the enclosing scope. This can be controlled by nesting blocks.
Elaborate
. Pragma Elaborate
only applies to library units. Language Ref Manual references: 3.2.1 Object Declarations, 3.9 Declarative Parts, 6.5 Function Subprograms
Direct_IO
and Sequential_IO
Direct_IO
and Sequential_IO
are in
range.
Unchecked_Conversion
, there is no check on the value obtained from the
read operations found in Direct_IO
and Sequential_IO
. See Guideline 5.9.1 for
an example.
Language Ref Manual references: 14.2.2 Sequential Input-Output, 14.2.4 Direct Input-Output
While an incorrect order dependency may not adversely affect the program on a certain implementation, the code might not execute correctly when it is ported. Avoid incorrect order dependencies, but also recognize that even an unintentional error of this kind could prohibit portability.
Language Ref Manual references: 6.4.1 Parameter Associations