Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni [email protected]...

117
Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni [email protected] http://libre.adacore.com/ Software_Matters

Transcript of Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni [email protected]...

Page 1: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Programming in the Small:C/C++/Java Pitfalls

& Ada Benefits

Franco [email protected]

http://libre.adacore.com/Software_Matters

Page 2: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 3

Suggested Reading

C Traps and Pitfalls• by Andrew Koenig (Addison Wesley)

Guidelines for the Use of the C Language in Vehicle Based Software

• Purchasing info at http://www.misra.org.uk/misra-c.htm

Multilanguage Programming on the JVM: The Ada 95 Benefits

• http://libre.act-europe.fr/Why_Ada/ada-on-jvm.pdf

Page 3: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 5

Lecture Summary

In this lecture we concentrate on programming in the small

We go over some Ada basic constructs• Procedures, functions, types, loops, if and case statements exceptions,

etc.

We show some C/C++/Java pitfalls

We show how Ada avoids them

Page 4: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 12

Programming in the Small with C

C makes the following assumption:• Trust the programmers, they never make mistakes• Favor program conciseness over its readability

But:• Programmers do make mistakes• Programs are written once but read many times

The C foundation of C++ & Java leads to fragile software• Software where it is easy to make mistakes• Software that is hard to read• Software that is hard to change

Page 5: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 14

Note on the Ada Development Environment

In this course we use GNAT GAP Edition

GNAT is widely available• You can download the sources of GNAT• Pre-built GNAT binaries available for: Linux, Solaris, Windows

GNAT GPL Edition available at • http://libre.adacore.com

Page 6: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Background on Ada ProgrammingA Simple Example

Page 7: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 16

Procedure Main

Procedure Main• Stored in file main.adb• Technically this is called a compilation unit

A compilation unit can be the body or the spec (specification) of a:

• procedure• function• package (see next lecture)

Spec = precise list of services exported

Body = implementation details

In GNAT: • 1 compilation unit per file • File name matches unit name• 2 file extensions possible

.adb = Ada Body .ads = Ada Spec

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

Note: Ada is case insensitiveNote: Ada is case insensitive

Page 8: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 17

Inside Procedure Main

Declarative part: Contains the declaration of:• Variable, types, nested procedures, nested

functions, ... used in procedure Main

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

Procedure statements

Page 9: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 18

with Text_IO;

List of compilation units whose services are used in procedure Main

Text_IO is the predefined Ada text Input/Output library

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

Procedures declared in library Text_IO and used in Main

Page 10: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 19

use Text_IO;

By putting a use clause you can (but don't have to) omit the Text_IO prefix inside Main

with Text_IO; use Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

with Text_IO; use Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length'img);Text_IO . Put_Line (Width'img);Text_IO . Put_Line (Height'img);

end Main;

Page 11: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 20

The ' img Attribute

' img is a predefined GNAT attribute • Given an integer or floating point number X,

X ' img returns its string representation• More on attributes later on

with Text_IO; use Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length ' img);Text_IO . Put_Line (Width ' img);Text_IO . Put_Line (Height ' img);

end Main;

with Text_IO; use Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length ' img);Text_IO . Put_Line (Width ' img);Text_IO . Put_Line (Height ' img);

end Main;

Page 12: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Structure of an Ada Program

Page 13: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 22

General Structure of an Ada Program

with …;procedure Some_Main is

…begin

…end Some_Main;

with …;procedure Some_Main is

…begin

…end Some_Main;

with …; with …;

with …; with …;

with …; with …;

with …; with …;

with …; with …;

Page 14: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 23

A Simple Example

with Display;with Fact;procedure Display_Fact isbegin

for K in 1 .. 4 loopDisplay ("Factorial", K, Fact (K));

end loop;end Display_Fact;

with Display;with Fact;procedure Display_Fact isbegin

for K in 1 .. 4 loopDisplay ("Factorial", K, Fact (K));

end loop;end Display_Fact;

with Text_IO; use Text_IO;procedure Display (S : String; X, Y : Integer) isbegin

Put_Line (S & " (" & X'img & ") = " & Y'img);end Display;

with Text_IO; use Text_IO;procedure Display (S : String; X, Y : Integer) isbegin

Put_Line (S & " (" & X'img & ") = " & Y'img);end Display;

function Fact (N : Integer) return Integer isbegin

if N <= 1 thenreturn 1;

elsereturn N * Fact (N - 1);

end if;end Fact;

function Fact (N : Integer) return Integer isbegin

if N <= 1 thenreturn 1;

elsereturn N * Fact (N - 1);

end if;end Fact;

Page 15: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 24

Building & Executing Display_Fact

GNAT has an automatic "make" facility: gnatmake

Gnatmake• Will compile or recompile the Ada

sources that need to be compiled• It will bind and link them

A make file is not necessary

Page 16: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 25

Note on the Concatenation Operator &

with Text_IO; use Text_IO;procedure Display (S : String; X, Y : Integer) isbegin

Put_Line (S & " (" & X'img & ") = " & Y'img);end Display;

with Text_IO; use Text_IO;procedure Display (S : String; X, Y : Integer) isbegin

Put_Line (S & " (" & X'img & ") = " & Y'img);end Display;

&& ==

1 dimensional arrays1 dimensional arrays

11 22 33 44 55 AA BB 11 22 33 44 55 AA BB

Page 17: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 26

with Display;with Fact;procedure Display_Fact isbegin

for K in 1 .. 4 loopDisplay ("Factorial", K, Fact (K));

end loop;end Display_Fact;

with Display;with Fact;procedure Display_Fact isbegin

for K in 1 .. 4 loopDisplay ("Factorial", K, Fact (K));

end loop;end Display_Fact;

Note on For Loops

In for loops, the loop variable (K in the example) is implicitly declared

The loop variable cannot be modified inside the for loop

The loop variable ceases to exist just after the loop

Page 18: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Numeric Pitfallin C/C++/Java

Page 19: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 28

#include <stdio.h>

int main () {int length = 8265;int width = 0252;int height = 8292;

printf ("length = %d\n", length);printf ("width = %d\n", width);printf ("height = %d\n", height);

}

#include <stdio.h>

int main () {int length = 8265;int width = 0252;int height = 8292;

printf ("length = %d\n", length);printf ("width = %d\n", width);printf ("height = %d\n", height);

}

What is the Program Output ?

This program compiles fine

What is its output?

Page 20: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 29

Surprised ?

Was this the programmer’s intent ?Was this the programmer’s intent ?

Page 21: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 30

Numbers in C/C++/Java

In C/C++/Java numbers starting with 0 are octal numbers

This is a bad choice • Error-prone• Hard-to-read

There is no way to specify numbers in base 2• Very surprising giving the fact that C was meant for to be a low-level

systems language

Never use octal numbers

Page 22: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 31

The Ada Version

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length ' img);Text_IO . Put_Line (Width ' img);Text_IO . Put_Line (Height ' img);

end Main;

with Text_IO;

procedure Main isLength : Integer := 8265;Width : Integer := 0252;Height : Integer := 8292;

beginText_IO . Put_Line (Length ' img);Text_IO . Put_Line (Width ' img);Text_IO . Put_Line (Height ' img);

end Main;

No surprises in Ada

No surprises in Ada

Page 23: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 32

Length : Integer := 8265;Width : Integer := 0252; -- regular decimal numberWidth_8 : Integer := 8#252#; -- octal number

B_Mask : Integer := 2#1100_1011#; -- binary number -- you can use “_” to separate digitsW_Mask : Integer := 16#FFF1_A4B0#; -- Hexadecimal number

Length : Integer := 8265;Width : Integer := 0252; -- regular decimal numberWidth_8 : Integer := 8#252#; -- octal number

B_Mask : Integer := 2#1100_1011#; -- binary number -- you can use “_” to separate digitsW_Mask : Integer := 16#FFF1_A4B0#; -- Hexadecimal number

Numbers in Ada

If no base is specified the number a decimal number

In Ada you can specify any base from 2 to 16 (for both integer and real

(floating point) numbers

Use the “_” to separate digits for clarity• 1_000_000_000

Page 24: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Lexical & Syntactic Pitfallsin C/C++/Java

Page 25: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 34

#include <limits.h>

/* If *y is zero and x > 0 set *k to the biggest positive integer. * If *y is zero and x <=0 leave *k unchanged. * If *y is not zero set *k to be x divided by *y and increment *y by 1. */void check_divide (int *k, int x, int *y) {

if (*y = 0)if (x > 0)

*k = INT_MAX;else

*k = x / *y /* it is safe to divide by *y since it cannot be 0 */;*y++;

}

#include <limits.h>

/* If *y is zero and x > 0 set *k to the biggest positive integer. * If *y is zero and x <=0 leave *k unchanged. * If *y is not zero set *k to be x divided by *y and increment *y by 1. */void check_divide (int *k, int x, int *y) {

if (*y = 0)if (x > 0)

*k = INT_MAX;else

*k = x / *y /* it is safe to divide by *y since it cannot be 0 */;*y++;

}

Is the Following Code Correct ?

This program compiles fine, but has a number of problems. Which ones?

Page 26: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 35

There are 4 Bugs

= versus ==• Using “=“ for assignment and “==“ for equality is a poor choice• Use a compiler that warns you when you use “=“ inside tests• This is a hard problem because C++ style encourages the use of “=“

inside tests:

Dangling else problem• Always bracket everything

Nested y++

Bad operator precedence *y++ means *(y++)• When in doubt use parentheses or separate tokens with white spaces ...

while (*s1++ = *s2++); while (*s1++ = *s2++);

Page 27: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 36

What about Java?

= versus ==• This problem exists in Java for boolean,

but has been fixed for other data types

Dangling else problem• Problem is still there

Bad operator precedence *j++ means *(j++)

• No * operator in Java. This Problem has been solved

boolean safety_flag;boolean danger_flag;…if (safety_flag = danger_flag) {

sound_alarm ();}

boolean safety_flag;boolean danger_flag;…if (safety_flag = danger_flag) {

sound_alarm ();}

This is OK in Java but is often a bugThis is OK in Java but is often a bug

Page 28: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 37

#include <limits.h>

/* If *y is null and x > 0 set *k to the biggest positive integer. * If *y is null and x <=0 leave *k unchanged. * If *y is non null set *k to be x divided by *y and increment *y by 1. */void check_divide (int *k, int x, int *y) {

if (*y == 0) {if ( x > 0)

*k = INT_MAX;}else {

*k = x / *y /* it is safe to divide by *y since it cannot be 0 */;(*y)++; /* or *y ++ */

}}

#include <limits.h>

/* If *y is null and x > 0 set *k to the biggest positive integer. * If *y is null and x <=0 leave *k unchanged. * If *y is non null set *k to be x divided by *y and increment *y by 1. */void check_divide (int *k, int x, int *y) {

if (*y == 0) {if ( x > 0)

*k = INT_MAX;}else {

*k = x / *y /* it is safe to divide by *y since it cannot be 0 */;(*y)++; /* or *y ++ */

}}

The Correct Version

Page 29: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 38

-- If Y = 0 and X > 0 set K to the biggest positive integer.-- If Y = 0 and X <= 0 leave K unchanged.-- If Y /= 0 set K to be X divided by Y and increment Y by 1.

procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer’Last; -- K is set to the largest Integer end if; else K := X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1; end if;end Check_Divide;

-- If Y = 0 and X > 0 set K to the biggest positive integer.-- If Y = 0 and X <= 0 leave K unchanged.-- If Y /= 0 set K to be X divided by Y and increment Y by 1.

procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer’Last; -- K is set to the largest Integer end if; else K := X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1; end if;end Check_Divide;

Ada Solves all the Previous Pitfalls

Page 30: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 39

-- If Y = 0 and X > 0 set K to the biggest positive integer.-- If Y = 0 and X <= 0 leave K unchanged.-- If Y /= 0 set K to be X divided by Y and increment Y by 1.

procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 and then X > 0 thenK := Integer’Last; -- K is set to the largest Integer

elsif Y /= 0 then K := X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1;end if;

end Check_Divide;

-- If Y = 0 and X > 0 set K to the biggest positive integer.-- If Y = 0 and X <= 0 leave K unchanged.-- If Y /= 0 set K to be X divided by Y and increment Y by 1.

procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 and then X > 0 thenK := Integer’Last; -- K is set to the largest Integer

elsif Y /= 0 then K := X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1;end if;

end Check_Divide;

Simpler Ada Version: "elsif" "and then"

Page 31: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 40

Lexical & Syntactic Clarity in Ada

= means equality while := means assignment• If you use one instead of the other you get a compiler error

No dangling else in Ada•

• If it isn't then you get a compiler error

In Ada comments start with -- and go to the end of the line. No other type of comment

No ++ operators in Ada

No need for a * operator in Ada

if … then … -- Must be terminated by an end if;end if;

if … then … -- Must be terminated by an end if;end if;

Page 32: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Side Note on Ada Attributes

Page 33: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 45

Attributes

Ada types, objects, and other entities can have attributes

An attribute is a property of the type, object, etc

Page 34: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 46

Example of Scalar Attributes

Given T some scalar type (Integer, Float, etc)

Given X an object of type T

T ' First Smallest value in T

T ' Last Largest value in T

T ' image (X) String representation of X

In GNAT you can use X ' img instead of T ' image (X)

In GNAT you can use X ' img instead of T ' image (X)

Page 35: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 47

procedure Check_Divide_And_Increment (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer’Last; -- K is set to the largest Integer end if; else K = X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1; end if;end Checked_Divide;

procedure Check_Divide_And_Increment (K : in out Integer; X : Integer; Y : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer’Last; -- K is set to the largest Integer end if; else K = X / Y; -- it is safe to divide by Y since it cannot be 0

Y := Y + 1; end if;end Checked_Divide;

Example of Integer ' Last

Page 36: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

More C/C++/Java Syntactic Pitfalls

Page 37: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 49

// If the signal ahead is clear then increase the speed.

void increase_speed_if_safe (int speed, int signal) {if (signal == CLEAR);

increase_speed ();}

// If the signal ahead is clear then increase the speed.

void increase_speed_if_safe (int speed, int signal) {if (signal == CLEAR);

increase_speed ();}

Is the Following Code Correct ?

This program compiles fine, but has a problem. Which one?

Page 38: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 51

// If the signal ahead is clear then increase the speed.

void increase_speed_if_safe (int speed, int signal) {if (signal == CLEAR);

increase_speed ();}

// If the signal ahead is clear then increase the speed.

void increase_speed_if_safe (int speed, int signal) {if (signal == CLEAR);

increase_speed ();}

Be Careful of Spurious Semicolons

Page 39: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 52

-- If the signal ahead is clear then increase the speed.

procedure increase_speed_if_safe (speed : integer; signal : integer) isbegin

if signal = CLEAR then increase_speed;

end if;end increase_speed_if_safe;

-- If the signal ahead is clear then increase the speed.

procedure increase_speed_if_safe (speed : integer; signal : integer) isbegin

if signal = CLEAR then increase_speed;

end if;end increase_speed_if_safe;

The Ada Version is Always Safe

If you writeif signal = CLEAR then ;

• You get a compiler error

Page 40: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 53

More Bad Luck in C/C++/Java:Enumerations and Switch Statements

enum Alert_Type {LOW, MEDIUM, HIGH, VERY_HIGH};// C or C++. Java does not have enumerations, you have to use ints instead

void handle_alert (enum Alert_Type alert) {switch (alert) {

case LOW:activate_camera ();

case MEDIUM:send_guard ();

case HIGH:sound_alarm ();

}}

void process_alerts () {handle_alert (2);…

enum Alert_Type {LOW, MEDIUM, HIGH, VERY_HIGH};// C or C++. Java does not have enumerations, you have to use ints instead

void handle_alert (enum Alert_Type alert) {switch (alert) {

case LOW:activate_camera ();

case MEDIUM:send_guard ();

case HIGH:sound_alarm ();

}}

void process_alerts () {handle_alert (2);…

This program compiles fine, but has a number of problems. Which ones?

Page 41: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 54

Defects in the Previous Code

void handle_alert (enum Alert_Type alert) {switch (alert) {

case LOW:activate_camera ();break;

case MEDIUM:send_guard ();break;

case HIGH:sound_alarm ();break;

case VERY_HIGH:alert_police ();break;

}}void process_alerts () {

handle_alert (HIGH);

void handle_alert (enum Alert_Type alert) {switch (alert) {

case LOW:activate_camera ();break;

case MEDIUM:send_guard ();break;

case HIGH:sound_alarm ();break;

case VERY_HIGH:alert_police ();break;

}}void process_alerts () {

handle_alert (HIGH);

Don't forget break statements

C/C++/Java do not check that you have treated all cases in the switch

case labels can be integers or (values of) any enum type, not just enum Alert_Type which in most cases will be an error

Page 42: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 55

Ada is Safer (and Less Verbose)

type Alert_Type is (LOW, MEDIUM, HIGH, VERY_HIGH);

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when HIGH =>

Sound_Alarm;when VERY_HIGH =>

Alert_Police;end case;

end Process_Alert;

type Alert_Type is (LOW, MEDIUM, HIGH, VERY_HIGH);

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when HIGH =>

Sound_Alarm;when VERY_HIGH =>

Alert_Police;end case;

end Process_Alert;

No break statements

Ada will check that you have treated all cases in the case statement

You can only use an object of type Alert_Type

Page 43: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 56

Combining Cases

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when HIGH

| VERY_HIGH =>Sound_Alarm;Alert_Police;

end case;end Process_Alert;

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when HIGH

| VERY_HIGH =>Sound_Alarm;Alert_Police;

end case;end Process_Alert;

Page 44: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 57

Using a Default Clause

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when others =>

Sound_Alarm;Alert_Police;

end case;end Process_Alert;

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM =>

Send_Guard;when others =>

Sound_Alarm;Alert_Police;

end case;end Process_Alert;

Ada "when others" is equivalent to C/C++/Java "default", and takes away most of the benefit of the checking for all cases covered

Page 45: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 58

Using a Range

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM .. VERY_HIGH =>

Send_Guard;Sound_Alarm;Alert_Police;

end case;end Process_Alert;

procedure Process_Alert (Alert : Alert_Type) isbegin

case Alert iswhen LOW =>

Activate_Camera;when MEDIUM .. VERY_HIGH =>

Send_Guard;Sound_Alarm;Alert_Police;

end case;end Process_Alert;

A range is a set of ordered values• MEDIUM .. VERY_HIGH = MEDIUM, HIGH, VERY_HIGH

Page 46: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 59

Enumeration Types in Ada

Enumerations are true types in Ada

In C enums are just integers

In C++ enums are implicitly converted to ints (not from ints)

type Alert is (LOW, MEDIUM, HIGH, VERY_HIGH);

procedure P (B : Integer) isA : Alert;

beginA := B;

type Alert is (LOW, MEDIUM, HIGH, VERY_HIGH);

procedure P (B : Integer) isA : Alert;

beginA := B; Compilation errorCompilation errorCompilation errorCompilation error

// C++enum Alert {LOW, MEDIUM, HIGH, VERY_HIGH};

int k = LOW; // accepted by C++Alert a = 1; // rejected by C++

// C++enum Alert {LOW, MEDIUM, HIGH, VERY_HIGH};

int k = LOW; // accepted by C++Alert a = 1; // rejected by C++

Page 47: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 61

Ada Enumeration Types and Attributes

Alert_Type ' First LOW

Alert_Type ' Last VERY_HIGH

Page 48: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 62

Predefined Enumerations in Ada

type Boolean is (False, True);

type Character is (…, 'a', 'b', 'c', …);

type Boolean is (False, True);

type Character is (…, 'a', 'b', 'c', …);

Page 49: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 63

Predefined Enumerations: Examples

function Is_Letter (C : Character) return Boolean isbegin

return (C in 'a' .. 'z') or (C in 'A' .. 'Z');end Is_Letter;

function Is_Letter (C : Character) return Boolean isbegin

return (C in 'a' .. 'z') or (C in 'A' .. 'Z');end Is_Letter;

function Is_Arithmetic_Operator (C : Character) return Boolean isbegin

case C iswhen '+' | '-' | '*' | '/' =>

return True;when others =>

return False;end case;

end Is_Arithmetic_Operator;

function Is_Arithmetic_Operator (C : Character) return Boolean isbegin

case C iswhen '+' | '-' | '*' | '/' =>

return True;when others =>

return False;end case;

end Is_Arithmetic_Operator;

Page 50: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

C/C++/Java Type System

Page 51: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 71

What is a Type?

A type is characterized by:

The set of values an expression of that type can take

The operations that can be applied to those values

Page 52: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 72

Pre-Defined and User-Defined Types

Some types can be pre-defined by the language• E.g. booleans, integers, characters, strings, etc

Pre-defined types come with pre-defined operations• E.g. for integers: additions, subtractions, etc.

Languages typically allow user-defined types and operations• User-defined operations are provided in the form of procedures and

functions

Page 53: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 78

Typing Problems Common to C/C++/Java

typedef in C/C++ is a shorthand it does not define a new type

No user-defined types• Scalars (characters, integers, reals)• Pointers (e.g. there can only be a single pointer to an int type) • Arrays (e.g. there can only be a single array of int type)

Implicit conversions from integers to reals

Weak overflow semantics rules for signed integers

Missing types• Enumerations in Java (not full types in C/C++)• Character types in C/C++• Fixed points• Unsigned integers in Java• Pointers to functions in Java

Page 54: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 80

C/C++ Example

The program to the left compiles fine

There is something wrong with it

What ?

typedef int Time;typedef int Distance;typedef int Speed; …const Speed SAFETY_SPEED = 120;…void increase_speed (Speed s);…void check_speed (Time t, Distance d) {

Speed s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void perform_safety_checks () {

Time t = get_time ();Distance d = get_distance ();…check_speed (d, t);

}

typedef int Time;typedef int Distance;typedef int Speed; …const Speed SAFETY_SPEED = 120;…void increase_speed (Speed s);…void check_speed (Time t, Distance d) {

Speed s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void perform_safety_checks () {

Time t = get_time ();Distance d = get_distance ();…check_speed (d, t);

}

Page 55: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 82

What's Wrong with C/C++

Program compiles fine but has 2 serious flaws that go undetected

FLAW 1: • t is a Time• increase_speed() takes a Speed

parameter• Time and Speed are conceptually

different, they should not be mixed up

FLAW 2: • Distance and Time parameters have been

inverted• Time and Distance are conceptually

different, they should not be mixed up

C/C++ provide NO HELP to the programmer in detecting these mistakes

typedef int Time;typedef int Distance;typedef int Speed; …const Speed SAFETY_SPEED = 120;…void increase_speed (Speed s);…void check_speed (Time t, Distance d) {

Speed s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void perform_safety_checks () {

Time t = get_time ();Distance d = get_distance ();…check_speed (d, t);

}

typedef int Time;typedef int Distance;typedef int Speed; …const Speed SAFETY_SPEED = 120;…void increase_speed (Speed s);…void check_speed (Time t, Distance d) {

Speed s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void perform_safety_checks () {

Time t = get_time ();Distance d = get_distance ();…check_speed (d, t);

}

Page 56: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 83

Things are Even Worse in Java

There are no typedef in Java

Everything must be an int

typedef are useful for documentation purposes

typedef could be used to perform sanity checks during code walkthroughs or with simple tools

This problem is particularly severe in Java given that many API calls have several indistinguishable int parameters:

• AdjustmentEvent (Adjustable source, int id, int type, int value)

final int SAFETY_SPEED = 120;…void check_speed (int t, int d) {

int s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void increase_speed (int s) { … }void perform_safety_checks () {

int t = get_time ();int d = get_distance ();…check_speed (d, t);

}

final int SAFETY_SPEED = 120;…void check_speed (int t, int d) {

int s = d/t;if (s < SAFETY_SPEED)

increase_speed (t);}void increase_speed (int s) { … }void perform_safety_checks () {

int t = get_time ();int d = get_distance ();…check_speed (d, t);

}

Page 57: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 84

What About Ada?

You can write the same buggy code in Ada, but …

… Ada has two lines of defense that do not exist in C/C++ or Java to protect the programmer• User defined types• Parameter associations

-- Buggy code. DON'T write this

SAFETY_SPEED : constant Integer := 120;…procedure Increase_Speed (S : Integer);…procedure Check_Speed (T : Integer; D : Integer) is

S : Integer := D / T;begin

if S < SAFETY_SPEED thenIncrease_Speed (T);

end if;end Check_Speed;

procedure Perform_Safety_Checks isT : Integer := Get_Time;D : Integer := Get_Distance;

begin…Check_Speed (D, T);

end Perform_Safety_Checks;

-- Buggy code. DON'T write this

SAFETY_SPEED : constant Integer := 120;…procedure Increase_Speed (S : Integer);…procedure Check_Speed (T : Integer; D : Integer) is

S : Integer := D / T;begin

if S < SAFETY_SPEED thenIncrease_Speed (T);

end if;end Check_Speed;

procedure Perform_Safety_Checks isT : Integer := Get_Time;D : Integer := Get_Distance;

begin…Check_Speed (D, T);

end Perform_Safety_Checks;

Page 58: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 85

Defining New Types in Ada

Users can define their own types in Ada

In C/C++/Java users can only define struct/union/class types• No user-defined scalar, pointer or array types

-- Example of integer type definition in Ada

type Time is range 0 .. 3_600;

type Distance is range 0 .. 1_000;

type Speed is range 0 .. 4_000;

-- Example of integer type definition in Ada

type Time is range 0 .. 3_600;

type Distance is range 0 .. 1_000;

type Speed is range 0 .. 4_000;

Page 59: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 86

User Defined Integer Types in Ada

Each user defined integer type introduces a new type

This new type is NOT a synonym of Integer

Each user defined integer type gives its bounds, i.e. the values any object of this type can take

• Time ' First = 0• Time ' Last = 3_600

type Time is range 0 .. 3_600;

type Distance is range 0 .. 1_000;

type Speed is range 0 .. 4_000;

type Time is range 0 .. 3_600;

type Distance is range 0 .. 1_000;

type Speed is range 0 .. 4_000;

Page 60: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 87

Ada is Strongly Typed (1 of 2)

When you define the proper types the Ada compiler catches the errors

To mix different types you must use explicit conversions in Ada

D is of type Distance, T is of type Time, S is of type Speed

• Only objects of the same type can be mixed together in this fashion

Increase_Speed is expecting a Speed parameter not a Time

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;

SAFETY_SPEED : constant Speed := 120;

procedure Increase_Speed (S : Speed);

procedure Check_Speed (T : Time; D : Distance) isS : Speed := D / T;

beginif S < SAFETY_SPEED then

Increase_Speed (T);end if;

end Check_Speed;…

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;

SAFETY_SPEED : constant Speed := 120;

procedure Increase_Speed (S : Speed);

procedure Check_Speed (T : Time; D : Distance) isS : Speed := D / T;

beginif S < SAFETY_SPEED then

Increase_Speed (T);end if;

end Check_Speed;…

Compilation Compilation errorerror

Compilation Compilation errorerror

Compilation Compilation errorerror

Compilation Compilation errorerror

Page 61: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 88

Ada is Strongly Typed (2 of 2)

Parameters switched

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;…procedure Check_Speed (T : Time; D : Distance); …procedure Perform_Safety_Checks is

T : Time := Get_Time;D : Distance := Get_Distance;

begin…Check_Speed (D, T);

end Perform_Safety_Checks;

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;…procedure Check_Speed (T : Time; D : Distance); …procedure Perform_Safety_Checks is

T : Time := Get_Time;D : Distance := Get_Distance;

begin…Check_Speed (D, T);

end Perform_Safety_Checks;

Compilation Compilation errorerror

Compilation Compilation errorerror

Page 62: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 89

The Correct Ada Version

You must convert D and T to Integer to perform the division

And then convert the result to type Speed

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;

SAFETY_SPEED : constant Speed := 120;procedure Increase_Speed (S : Speed);

procedure Check_Speed (T : Time; D : Distance) isS : Speed := Speed ( Integer(D) / Integer (T));

beginif S < SAFETY_SPEED then

Increase_Speed (S);end if;

end Check_Speed;procedure Perform_Safety_Checks is

T : Time := Get_Time;D : Distance := Get_Distance;

begin…Check_Speed (T, D);

end Perform_Safety_Checks;

type Time is range 0 .. 3_600;type Distance is range 0 .. 1_000;type Speed is range 0 .. 4_000;

SAFETY_SPEED : constant Speed := 120;procedure Increase_Speed (S : Speed);

procedure Check_Speed (T : Time; D : Distance) isS : Speed := Speed ( Integer(D) / Integer (T));

beginif S < SAFETY_SPEED then

Increase_Speed (S);end if;

end Check_Speed;procedure Perform_Safety_Checks is

T : Time := Get_Time;D : Distance := Get_Distance;

begin…Check_Speed (T, D);

end Perform_Safety_Checks;

Page 63: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 90

But What About?

How do you know it wasSafe_Copy (X, Y)

and notSafe_Copy (Y, X)

You don't. That's why Ada provides name parameters

type A_Type is …;

procedure Safe_Copy (Source : A_Type; Target : A_Type);

procedure Try isX : A_Type := …;Y : A_Type := …;

beginSafe_Copy (X, Y);…

end Try;

type A_Type is …;

procedure Safe_Copy (Source : A_Type; Target : A_Type);

procedure Try isX : A_Type := …;Y : A_Type := …;

beginSafe_Copy (X, Y);…

end Try;

Page 64: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 91

Ada has Named Parameters

type A_Type is …;

procedure Safe_Copy (Source : A_Type; Target : A_Type);

procedure Try isX : A_Type := …;Y : A_Type := …;

beginSafe_Copy (Source => X, Target => Y);…

end Try;

type A_Type is …;

procedure Safe_Copy (Source : A_Type; Target : A_Type);

procedure Try isX : A_Type := …;Y : A_Type := …;

beginSafe_Copy (Source => X, Target => Y);…

end Try;

Named parameterNamed parameterNamed parameterNamed parameter

Page 65: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 92

Avoiding Parameter Confusion in Ada

Summary: Two lines of defense

User defined types

Named parameters

Page 66: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Example of C/C++/Java Type System Weakness

Signed Integer Overflow Semantics

Page 67: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 94

Overflow in C/C++/Java

In C/C++ signed integer overflow is undefined, anything can happen• All known implementations "wrap around"

In Java wrap around semantics are part of the language

#include <limits.h>

void compute () {int k = INT_MAX;

k = k + 1;}

#include <limits.h>

void compute () {int k = INT_MAX;

k = k + 1;}

Page 68: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 95

Overflow in Ada

EVERY time there is an integer overflow in Ada an exception is raised

procedure Compute isK : Integer := Integer'Last;

beginK := K + 1;

end Compute;

procedure Compute isK : Integer := Integer'Last;

beginK := K + 1;

end Compute;

Exception raised Exception raised at execution at execution

timetime

Exception raised Exception raised at execution at execution

timetime

Page 69: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 96

Example: Overflow in Action in Ada

In GNAT you have to use the switch -gnato to ask for integer overflow checking

Page 70: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 97

The Pernicious Effects of Wrap-Around Semantics: A Java Example

The program to the left compiles fine, and runs …

… But there is something wrong with it. What ?

final int RADIO_PORT = …;

void open (int port) {…}void send (int port, byte data) {…}void close (int port) {…}

void send_bytes (byte first_byte, byte last_byte) {open (RADIO_PORT);for (byte b = first_byte; b <= last_byte; b++) {

send (RADIO_PORT, b);}close (RADIO_PORT);

}

final int RADIO_PORT = …;

void open (int port) {…}void send (int port, byte data) {…}void close (int port) {…}

void send_bytes (byte first_byte, byte last_byte) {open (RADIO_PORT);for (byte b = first_byte; b <= last_byte; b++) {

send (RADIO_PORT, b);}close (RADIO_PORT);

}

Page 71: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 98

Infinite Loop when last_byte == 127

Two problems:

Wrap around semantics of type byte• When last_byte = b = 127 we execute the loop, we do b++ and b wraps to -128

There is no real for loop instruction in C/C++/Javafor (x; y; z) {…}

• Meansx; while (y) { …; z; }

Page 72: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 99

The Ada Version is Safe

The code on the left runs fine

There is a true for loop in Ada (unlike C/C++/Java)

type Port is range 0 .. 255;type Byte is range -128 .. 127;

RADIO_PORT : constant Port := …;

procedure Open (P : Port);procedure Send (P : Port; B : Byte);procedure Close (P : Port);

procedure Send_Bytes (First : Byte; Last : Byte) isbegin

Open (RADIO_PORT);for B in First .. Last loop

Send (RADIO_PORT, B);end loop;Close (RADIO_PORT);

end Send_Bytes;

type Port is range 0 .. 255;type Byte is range -128 .. 127;

RADIO_PORT : constant Port := …;

procedure Open (P : Port);procedure Send (P : Port; B : Byte);procedure Close (P : Port);

procedure Send_Bytes (First : Byte; Last : Byte) isbegin

Open (RADIO_PORT);for B in First .. Last loop

Send (RADIO_PORT, B);end loop;Close (RADIO_PORT);

end Send_Bytes;

Page 73: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 100

Checks and Overflows Summary

In Ada• Every integer overflow raises an exception in Ada• Every division by zero raises an exception in Ada• Every array index overflow raises an exception in Ada• Etc.• You can disable all the Ada checks for deployment if you wish

In Java• Java adopted most of the Ada checks except for integer overflow which

wraps around in Java• Cannot disable checks in Java

In C/C++• No checks

Page 74: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Side Notes on Ada Types

Page 75: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 102

Unsigned Integers

Ada has the choice of two sorts of integer types:• Signed integers (an exception is raised in case of an overflow)• Unsigned integers (wrap-around semantics)

-- Example of unsigned integers in Ada

procedure Try istype Hash_Index is mod 1023;H : Hash_Index := 1022;

beginH := H + 1;-- H is equal to zero here

end Try;

-- Example of unsigned integers in Ada

procedure Try istype Hash_Index is mod 1023;H : Hash_Index := 1022;

beginH := H + 1;-- H is equal to zero here

end Try;

Page 76: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 103

Subtypes

Sometimes you want to add additional constraints to a type without creating a new type

Ada provides the notion of subtype for that

-- Example of unsigned integers in Ada

procedure Try istype Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);subtype Working_Day is Day range Mon .. Fri;

D : Day := Mon;WD : Working_Day;

beginWD := D; -- This is OKWD := Sun; -- This raises an exception

end Try;

-- Example of unsigned integers in Ada

procedure Try istype Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);subtype Working_Day is Day range Mon .. Fri;

D : Day := Mon;WD : Working_Day;

beginWD := D; -- This is OKWD := Sun; -- This raises an exception

end Try;

Page 77: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 104

Predefined Ada Subtypes

subtype Natural is Integer range 0 .. Integer ’ Last;

subtype Positive is Natural range 1 .. Natural ’ Last;

subtype Natural is Integer range 0 .. Integer ’ Last;

subtype Positive is Natural range 1 .. Natural ’ Last;

Page 78: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Exceptions in Ada

Page 79: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 106

When a Check Fails an Exception is Raised in Ada

Page 80: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 107

Ada Predefined Exceptions

The following predefined exceptions are raised when something goes wrong in an Ada program

Constraint_ErrorConstraint_Errorinteger overflow, computation error (divide by zero), array index out of range, null pointer dereferencing, …

Storage_ErrorStorage_Error no more memory available

Program_ErrorProgram_Errorfundamental program error (e.g. end of function with no return statement)

Page 81: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 108

Creating Your Own Exceptions

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

end Checks;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

end Checks;

Page 82: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 109

What Happens at Execution Time?

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

end Checks;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

end Checks;

11

22

ExceptionExceptionraisedraised33

Page 83: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 110

Page 84: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 111

Displaying the Traceback(How you Got There)

with Ada.Exceptions; use Ada.Exceptions;with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;with Text_IO; use Text_IO;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen E : others =>

Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E));end Checks;

with Ada.Exceptions; use Ada.Exceptions;with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;with Text_IO; use Text_IO;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen E : others =>

Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E));end Checks;

Exception HandlerException Handler

Page 85: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 112

-cargs: Compiler arguments:-g: debugging on-gnatl: print out a program listing-gnato: overflow checks on

-cargs: Compiler arguments:-g: debugging on-gnatl: print out a program listing-gnato: overflow checks on

-bargs: Program binder arguments:-E: give exception tracebacks

-bargs: Program binder arguments:-E: give exception tracebacks

Page 86: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 113

What Happens at Execution Time

with Ada.Exceptions; use Ada.Exceptions;with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;with Text_IO; use Text_IO;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen E : others =>

Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E));end Checks;

with Ada.Exceptions; use Ada.Exceptions;with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;with Text_IO; use Text_IO;

procedure Checks isInternal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen E : others =>

Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E));end Checks;

aa

bb

dd

cc

ee

Page 87: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 114

Catching a Predefined Exception

with Text_IO; use Text_IO;procedure Checks is A : Integer := Integer ’ First;begin A := A - 1;exception when Constraint_Error => Put_Line (“Overflow occurred”);end Checks;

with Text_IO; use Text_IO;procedure Checks is A : Integer := Integer ’ First;begin A := A - 1;exception when Constraint_Error => Put_Line (“Overflow occurred”);end Checks;

Page 88: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 115

Catching Your Own Exceptionswith Text_IO; use Text_IO;procedure Checks is

Internal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen Internal_Error =>

Put_Line (“problem occurred”); when others => Put_Line (“some other exception”); end Checks;

with Text_IO; use Text_IO;procedure Checks is

Internal_Error : Exception;

procedure Foo isbegin

raise Internal_Error;end Foo;

procedure Bar isbegin

Foo;end Bar;

begin -- of ChecksBar;

exceptionwhen Internal_Error =>

Put_Line (“problem occurred”); when others => Put_Line (“some other exception”); end Checks;

Page 89: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 116

procedure Checks is…

begin -- of Checks:::::::::::::::

end Checks;

procedure Checks is…

begin -- of Checks:::::::::::::::

end Checks;

Catching an Exception Where You Want

to catch someto catch someexception in a regionexception in a regionof code without exitingof code without exitingfrom the subprogram from the subprogram you can use a declare blockyou can use a declare block

Page 90: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 117

procedure Calc (A, B : Float) is C, D : Float;begin

declareOld_C : Float := C;

begin C := A * B; D := C ** 2; exception when Constraint_Error => C := Old_C;

D := 0.0; end;

end Calc;

procedure Calc (A, B : Float) is C, D : Float;begin

declareOld_C : Float := C;

begin C := A * B; D := C ** 2; exception when Constraint_Error => C := Old_C;

D := 0.0; end;

end Calc;

Example of a Declare Block

Page 91: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Array Pitfalls in C

Page 92: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 129

Arrays in Ada

Ada has real arrays (1-dimensional and multi-dimensional)

Ada array can have its size determined at run-time• Local variable length arrays are allowed in the latest C standard (C99)

Ada array bounds can be arbitrary, lower bound does not have to start at 0

Page 93: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 130

One of a Kind Arrays

In Ada Arrays can have arbitrary bounds

The bounds can be dynamic values

procedure Compute (N : Integer) is

A : array (1 .. N) of Float;

begin…

end Compute;

procedure Compute (N : Integer) is

A : array (1 .. N) of Float;

begin…

end Compute;

Page 94: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 131

procedure Compute (N : Integer) istype Arr is array (Integer range <>) of Float;

A : Arr (1 .. N) := (others => 9);B : Arr := A;C : Arr (11 .. 20) := (1, 2, others => 0);

beginC := A;C (15 .. 18) := A (5 .. 8);

end Compute;

procedure Compute (N : Integer) istype Arr is array (Integer range <>) of Float;

A : Arr (1 .. N) := (others => 9);B : Arr := A;C : Arr (11 .. 20) := (1, 2, others => 0);

beginC := A;C (15 .. 18) := A (5 .. 8);

end Compute;

Typed Arrays

B takes its bounds from A

If C'Length /= A'Length then Constraint_Error is raised

If A'Last < 8 then Constraint_Error is raised

Page 95: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 132

Arrays in Ada are Safe

If you try to index a non-existent arry position, a Constraint_Error exception is raised

procedure Checks isA : array (1 .. 100) of Integer;

beginA (101) := 1;

end Checks;

procedure Checks isA : array (1 .. 100) of Integer;

beginA (101) := 1;

end Checks;Exception raisedException raised

Page 96: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 133

Example of 1-Dim Array Attributes

Given A some array object• A : array (10 .. 99) of Integer;

A ' First 10

A ' Last 99

A ' Length 90

A ' Range 10 .. 99

Page 97: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 134

procedure Calc istype Vector is array (Natural range <>) of Float;

function Max (V : Vector) return Float is M : Float := Float ’ First;

begin for K in V ’ Range loop if V (K) > M then M := V (K); end if; end loop; return M;

end Max;

V1 : Vector := (1.0, 2.0, 3.0); -- V'First = 0 and V'Last = 2V2 : Vector (1 .. 100) := (1.0, 2.0, others => 5.0);

X : Float := Max (V1); -- X = 3.0Y : Float := Max (V2); -- Y = 5.0

begin…

end Calc;

procedure Calc istype Vector is array (Natural range <>) of Float;

function Max (V : Vector) return Float is M : Float := Float ’ First;

begin for K in V ’ Range loop if V (K) > M then M := V (K); end if; end loop; return M;

end Max;

V1 : Vector := (1.0, 2.0, 3.0); -- V'First = 0 and V'Last = 2V2 : Vector (1 .. 100) := (1.0, 2.0, others => 5.0);

X : Float := Max (V1); -- X = 3.0Y : Float := Max (V2); -- Y = 5.0

begin…

end Calc;

Ada Arrays are Powerful: No Need to Pass Array Bounds as in C/C++/Java

Page 98: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 135

Ada String Predefined Array Type

type String is array (Positive range <>) of Character;

R : String (1 .. 10);

S : String := (‘H’, ‘e’, ‘l’, ‘l’, ‘o’);T : String := “Hello”;

Q : String := S & “ “ & T & “ you”;-- Q = "Hello Hello you"

type String is array (Positive range <>) of Character;

R : String (1 .. 10);

S : String := (‘H’, ‘e’, ‘l’, ‘l’, ‘o’);T : String := “Hello”;

Q : String := S & “ “ & T & “ you”;-- Q = "Hello Hello you"

Page 99: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Records and Pointers in Ada

Page 100: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 137

Record Types

type Date is record Day : Positive range 1 .. 31; Month : Positive range 1 .. 12; Year : Integer;end record;

D : Date := (3, 9, 1975);

A : Date := (Day => 31, Month => 12, Year => 1999);

B : Date := A;

Y : Integer := B . Year;

type Date is record Day : Positive range 1 .. 31; Month : Positive range 1 .. 12; Year : Integer;end record;

D : Date := (3, 9, 1975);

A : Date := (Day => 31, Month => 12, Year => 1999);

B : Date := A;

Y : Integer := B . Year;

Page 101: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 138

type Node;type Node_Ptr is access Node;

type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr;end record;

P1 : Node_Ptr := new Node;P2 : Node_Ptr := new Node ’ ((3, 9, 1975), P1);

type Node;type Node_Ptr is access Node;

type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr;end record;

P1 : Node_Ptr := new Node;P2 : Node_Ptr := new Node ’ ((3, 9, 1975), P1);

Memory

1

1

1900

null

3

9

1975

Pointers and Records

Page 102: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 139

N : Node := ((31, 12, 1999), null);

P3 : Node_Ptr := new Node ’ (N);

Memory

31

12

1999

null

Page 103: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 140

Accessing Record Fields: A Simple Rule

If P is a pointer to a record then

P.all points to the WHOLE record

P.Field points to Field in the record

Note: P.Field is the same as P.all.Field

type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr;end record;

P : Node_Ptr := new Node;

A_Date : Date := P.D;A_Node : Node_Ptr := P.Next;

type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr;end record;

P : Node_Ptr := new Node;

A_Date : Date := P.D;A_Node : Node_Ptr := P.Next;

Page 104: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 141

Parametrized Records: Discriminants

type Q_Array (Positive range <>) of Integer;

type Queue (Max_Size : Positive) is record First : Positive := 1; Last : Positive := 1; Size : Natural := 0; Q : Q_Array (1 .. Max_Size);end record;

X : Queue (4); -- X.Max_Size = 4

Y : Queue;

type Q_Array (Positive range <>) of Integer;

type Queue (Max_Size : Positive) is record First : Positive := 1; Last : Positive := 1; Size : Natural := 0; Q : Q_Array (1 .. Max_Size);end record;

X : Queue (4); -- X.Max_Size = 4

Y : Queue; Compilation ErrorCompilation ErrorValue for Max_Size missingValue for Max_Size missing

Page 105: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Parameter Passing in C, Java and Ada

Page 106: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 147

Three Parameter Passing Modes in Adaprocedure Open_File (X : String);

procedure Open_File (X : in String); in

• It's the default mode, the in can be omitted

• Inside the procedure or function X is a constant initialized by the value of the actual parameter

• Functions can only have parameters of mode i

function Log (X : Float) return Float;

function Log (X : in Float) return Float;

procedure Increment (X : in out Float);

in out

• Inside the procedure X is a variable initialized by the value of the actual parameter

• The actual parameter is updated with the last value of X when the procedure terminates.

procedure Copy (Y : Float; X : out Float);

out

• Inside the procedure X is an uninitialized variable

• The actual parameter is updated with the last value of X when the procedure terminates

Page 107: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 148

Example: Mode "in"

function Log (X : Float) return Float isbegin

X := 1.0;…

end Log;

function Log (X : Float) return Float isbegin

X := 1.0;…

end Log;

Compilation errorCompilation errorX is a constant inside LogX is a constant inside Log

Compilation errorCompilation errorX is a constant inside LogX is a constant inside Log

Page 108: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 149

procedure A_Test is

procedure Increment (X : in out Float) isbegin

X := X + 1.0;end Increment;

Value : Float := 9.0;

begin-- Value = 9.0 hereIncrement (Value);-- Value = 10.0 here

end A_Test;

procedure A_Test is

procedure Increment (X : in out Float) isbegin

X := X + 1.0;end Increment;

Value : Float := 9.0;

begin-- Value = 9.0 hereIncrement (Value);-- Value = 10.0 here

end A_Test;

Example: Mode "in out"

NoteNote: In Ada You can nest : In Ada You can nest functions & proceduresfunctions & procedures

NoteNote: In Ada You can nest : In Ada You can nest functions & proceduresfunctions & procedures

Page 109: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 150

procedure A_Test is

procedure Copy (Y : Float; X : out Float) isbegin

X := Y;end Copy;

Value : Float;

begin-- Value is uninitialized hereCopy (10.0, Value);-- Value = 10.0 here

end A_Test;

procedure A_Test is

procedure Copy (Y : Float; X : out Float) isbegin

X := Y;end Copy;

Value : Float;

begin-- Value is uninitialized hereCopy (10.0, Value);-- Value = 10.0 here

end A_Test;

Example: Mode "out"

Page 110: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Ada Offers a Comprehensive Scheme for Safe Low-Level Programming

Page 111: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 152

PSW Example

Represent the following program status word (PSW):

PSW is 24 bits

Bits 0 to 7 contain a 7 bit system mask

Bits 12 to 15 contain a 4 digit protection key

Bits 20 to 24 contain the status flags of the machine for the program• The fours flags are called: A, M, W and P

All other bits are unused

System Mask unused Protection Key unused Machine

State0 7 8 11 12 15 16 19 20 23

Page 112: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 153

The PSW Type in Ada

type State is (A, M, W, P);type Byte_Mask is array (0 .. 7) of Boolean;type State_Mask is array (State) of Boolean;

type Program_Status_Word is recordSystem_Mask : Byte_Mask;Protection_Key : Integer range 0 .. 15;Machine_State : State_Mask;

end record;

for Program_Status_Word use recordSystem_Mask at 0 range 0 .. 7;Protection_Key at 0 range 12 .. 15;Machine_State at 0 range 20 .. 23;

end record;

for Program_Status_Word ' Size use 3 * System.Storage_Unit;

type State is (A, M, W, P);type Byte_Mask is array (0 .. 7) of Boolean;type State_Mask is array (State) of Boolean;

type Program_Status_Word is recordSystem_Mask : Byte_Mask;Protection_Key : Integer range 0 .. 15;Machine_State : State_Mask;

end record;

for Program_Status_Word use recordSystem_Mask at 0 range 0 .. 7;Protection_Key at 0 range 12 .. 15;Machine_State at 0 range 20 .. 23;

end record;

for Program_Status_Word ' Size use 3 * System.Storage_Unit;

System Mask unused Protection Key unused Machine

State0 7 8 11 12 15 16 19 20 23

Page 113: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 154

Accessing PSW Fields in Ada is …

Simple

Safe

Efficient

PSW : Program_Status_Word := …;

Key : Integer := PSW . Protection_Key;M_State : Boolean := PSW . Machine_State (M);Mask_3 : Boolean := PSW . System_Mask (3);

PSW : Program_Status_Word := …;

Key : Integer := PSW . Protection_Key;M_State : Boolean := PSW . Machine_State (M);Mask_3 : Boolean := PSW . System_Mask (3);

…type Program_Status_Word is record

System_Mask : Byte_Mask;Protection_Key : Integer range 0 .. 15;Machine_State : State_Mask;

end record;…

…type Program_Status_Word is record

System_Mask : Byte_Mask;Protection_Key : Integer range 0 .. 15;Machine_State : State_Mask;

end record;…

Page 114: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 155

There is more in Ada to help with safe and efficient

low-level programming than just the previous example

Page 115: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

Summary: Better Safe than Sorry

Page 116: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 161

Language Safety and Security

C++C++CC JavaJava AdaAdaunsafeunsafe safesafeassemblyassembly

Page 117: Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com .

http://libre.adacore.com © AdaCore under the GNU Free Documentation License 162

Summary

A good programming language • Encourages the writing of correct software• Helps in detecting errors

C/C++/Java• Encourage the writing of concise code not correct software• C/C++ provide no help in detecting errors• Java provides some help

Ada (and other languages such as Eiffel)• Encourage the writing of correct software• Provide help in detecting errors