+ All Categories
Home > Technology > Developing Software that Matters II

Developing Software that Matters II

Date post: 25-Jan-2015
Category:
Upload: gneuromante-canaladaorg
View: 1,049 times
Download: 4 times
Share this document with a friend
Description:
Author: ACT Europe. License: GFDL Slides objectives: Help you build software that are more: • Dependable • Adaptable • Fun to develop Show problems & pitfalls in • Functionality-oriented C-derived languages • C, C++, Java • Object-oriented • Structural problems
158
© ACT Europe under the GNU Free Documentation License Programming in the Small: Common C/C++/Java Pitfalls & How Ada Avoids them Franco Gasperoni [email protected] http://libre.act-europe.fr/Software_Matters
Transcript
Page 1: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

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

& How Ada Avoids themFranco Gasperoni

[email protected]://libre.act-europe.fr/Software_Matters

Page 2: Developing Software that Matters II

2http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Copyright Notice

► © ACT Europe under the GNU Free Documentation License

► Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; provided its original author is mentioned and the link to http://libre.act-europe.fr/ is kept at the bottom of every non-title slide. A copy of the license is included in available at:

http://www.fsf.org/licenses/fdl.html

Page 3: Developing Software that Matters II

3http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 4: Developing Software that Matters II

4http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Other Interesting Material

► Other Interesting Links� http://www.elj.com/cppcv3/

- A critique of C++� http://www.cs.mdx.ac.uk/harold/srf/javaspae.html

- A critique of Java� http://www.jaegers.net/humor/stroustrup.php

- Stroustrup's interview leaked� http://www.web-hits.org/txt/codingunmaintainable.html

- How to write unmaintainable code► Other interesting books

� Effective C++, by Scott Myers (Addison Wesley)� Java Pitfalls, by Michael C. Daconta et al., (Wiley)� Objects Unencapsulated: Java, Eiffel, and C++, by Ian Joyner

(Prentice Hall)

Page 5: Developing Software that Matters II

5http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Lecture Summary

► In this lecture we concentrate on programming in the small

► We show some common C/C++/Java pitfalls when programming in the small

► We show how Ada avoids them

Page 6: Developing Software that Matters II

6http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What is Programming in the Small ?

► A computer can perform only very simple operations► A program performs complex tasks by grouping together large numbers of

simple operations► Programming in the large

� Designing the abstractions and structure around which the simple computer operations will be organized

� The structuring unit varies from language to language (e.g. module, package, class, file, etc.)

� This is like doing the architectural drawing of a building► Programming in the small

� Sometimes called coding, this activity refers to filling in the details of the above design

� The details are the explicit, step-by-step instructions for performing fairly small-scale tasks: arithmetic operations, loops, decisions, etc.

Page 7: Developing Software that Matters II

7http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Programming: Abstraction, Structure & Coding Detail

Structuring element:Module, package, class, file, …

Uses the services of

Page 8: Developing Software that Matters II

8http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Programming in the Large:Abstraction & Structure

Page 9: Developing Software that Matters II

9http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Programming in the Small:Coding Detail

.

.

.if (TYPE_CONVENTION_FORTRAN_P (TREE_TYPE (gnu_array_object)))

for (i = ndim - 1, gnat_temp = First (Expressions (gnat_node));i >= 0;i--, gnat_temp = Next (gnat_temp))

gnat_expr_array[i] = gnat_temp;else

for (i = 0, gnat_temp = First (Expressions (gnat_node));i < ndim;i++, gnat_temp = Next (gnat_temp))

gnat_expr_array[i] = gnat_temp;...

Page 10: Developing Software that Matters II

10http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 11: Developing Software that Matters II

11http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Important Note

► All C/C++/Java code examples showed in this lecture compile� They are "correct" according to the C/C++/Java semantics� But they contain some serious FLAWS (they have bugs that are not

detected by C/C++/Java)

► Most of the pitfalls shown in this lecture are written in C/C++� They can easily be converted to Java

► Some pitfalls only occur in C/C++ and not in Java� When this is the case it will be pointed out in the example

► This lecture is not an exhaustive list of C/C++/Java pitfalls� There are many more

Page 12: Developing Software that Matters II

12http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Note on the Ada Compiler

► In this course we use GNAT� GNAT is the GNU Ada 95 compiler

► GNAT is widely available� You can download the sources of GNAT� Pre-built GNAT binaries available for

- Linux, Solaris, Windows NT/2000

► Available at � http://libre.act-europe.fr/GNAT/

Page 13: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

C/C++ Consistency Problems

Page 14: Developing Software that Matters II

14http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

printf (length);printf (width);printf (height);

}

What is the Program Output ?

► This program compiles fine

► What is its output?

Page 15: Developing Software that Matters II

15http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

The Program Crashes. Why?

Page 16: Developing Software that Matters II

16http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

printf (length);printf (width);printf (height);

}

Where does printf() Come From?

► A default printf is defined in the C standard library as:- int printf (const char *format, �)

► C philosophy: The programmer is always right� C compiler assumes there is a routine somewhere with signature:

- void printf (int);� The programmer must link with the library containing the correct printf

Page 17: Developing Software that Matters II

17http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

The Ada guarantee:If it runs it is consistent

Page 18: Developing Software that Matters II

18http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Note: Ada is case insensitive

Page 19: Developing Software that Matters II

19http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

► Procedure statements

Page 20: Developing Software that Matters II

20http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

► Procedures declared in library Text_IO and used in Main

Page 21: Developing Software that Matters II

21http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Ada Guarantees Consistency

► Compiler� Checks that you "with" a unit

before using its services� Checks that you use the

services of with-ed units correctly

► Binder/Linker� Check that the object of the

units in the program you are trying to link are the correct ones

Page 22: Developing Software that Matters II

22http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

C Does not Guarantee Consistency

► You can improve the situation as follows:

► Always #include the headers of the files whose services your are using

► Check all the warnings► If you are not sure which objects

you are linking delete all objects and recompile everything before linking

► There are additional tricks

Page 23: Developing Software that Matters II

23http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What about C++ and Java?

► C++� Same problem as in C� Not only for its C subset but also for C++ methods

► Java� Problem partly fixed by checks performed by the Java Virtual Machine

at execution time� The problem still exists in the presence of implicit conversions

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

Page 24: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Notes on the Ada Example

Page 25: Developing Software that Matters II

25http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

use Text_IO;

► By putting a use clause you can (but don't have to) omit the Text_IO prefix inside Mainwith 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 26: Developing Software that Matters II

26http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

The ' img Attribute

► ' img is a predefined 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;

Page 27: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Structure of an Ada Program

Page 28: Developing Software that Matters II

28http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

General Structure of an Ada Program

with �;procedure Some_Main is

�begin

�end Some_Main;

with �; with �; with �;

with �;with �;

Page 29: Developing Software that Matters II

29http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 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;

Page 30: Developing Software that Matters II

30http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 31: Developing Software that Matters II

31http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

& =

1 dimensional arrays

5544332211 BBAA 5544332211 BBAA

Page 32: Developing Software that Matters II

32http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 (Kin the example) is implicitely declared

► The loop variable cannot be modified inside the for loop

► The loop variable ceases to exist just after the loop

Page 33: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

C/C++/Java Numeric Pitfall

Page 34: Developing Software that Matters II

34http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

#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 35: Developing Software that Matters II

35http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Surprised ?

Was this the programmer’s intent ?

Page 36: Developing Software that Matters II

36http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 37: Developing Software that Matters II

37http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 digits

W_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 38: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Some C/C++ Lexical & Syntactic Pitfalls

Page 39: Developing Software that Matters II

39http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

#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++;

}

Is the Following Code Correct ?

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

Page 40: Developing Software that Matters II

40http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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:while (*s1++ = *s2++);

► Dangling else problem� Always bracket everything

► Nestested y++► Bad comment

� Use //-style comments, never /* */ if your C compiler supports it� Watch out for nested /* */ comments (/* /* */ */)

► Bad operator precedence *y++ means *(y++)� Put parentheses everywhere...

Page 41: Developing Software that Matters II

41http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 comment� 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 ();}

This is OK in Java but is often a bug

Page 42: Developing Software that Matters II

42http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

#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)++;

}}

The Correct Version

Page 43: Developing Software that Matters II

43http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

-- 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.

procedure Check_Divide (K : in out Integer; I : Integer; J : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer�Last; -- K is set to the largest Integerend if;

elseK := X / Y; -- it is safe to divide by Y since it cannot be 0Y := Y + 1;

end if;end Check_Divide;

Ada Solves all the Previous Pitfalls

Page 44: Developing Software that Matters II

44http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

-- 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.

procedure Check_Divide (K : in out Integer; I : Integer; J : in out Integer) isbegin

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

elsif Y /= 0 thenK := X / Y; -- it is safe to divide by Y since it cannot be 0Y := Y + 1;

end if;end Check_Divide;

Simpler Ada Version: "elsif" "and then"

Page 45: Developing Software that Matters II

45http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 … then must be terminated with an end if;� 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

Page 46: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Side Note on Ada Attributes

Page 47: Developing Software that Matters II

47http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Attributes

► Ada types, objects, and other entities can have attributes

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

Page 48: Developing Software that Matters II

48http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Example of Scalar Attributes

► Given T some scalar type (Integer, Float, etc)► Given X an object of type T

String representation of XT ' image (X)

Largest value in TT ' Last

Smallest value in TT ' First

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

Page 49: Developing Software that Matters II

49http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

procedure Check_Divide_And_Increment (K : in out Integer; I : Integer; J : in out Integer) isbegin

if Y = 0 thenif X > 0 then

K := Integer�Last; -- K is set to the largest Integerend if;

elseK = X / Y; -- it is safe to divide by Y since it cannot be 0

end if;Y := Y + 1;

end Checked_Divide;

Example of Integer ' Last

Page 50: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

More C/C++/Java Syntactic Pitfalls

Page 51: Developing Software that Matters II

51http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

// In file1int totalLength = 0;

Case Sensitivity Is Error-Prone

► C, C++ and Java are case-sensitive, Ada is case insensitive� K and k refer to two different things in C, C++, Java� K and k refer to the same thing in Ada

► This is error-prone

// In file2int totallength = 0;

// In file3void addLength (int length) {

totallength += length;}

Page 52: Developing Software that Matters II

52http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

// 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 53: Developing Software that Matters II

53http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Bugs can Have Serious Consequences

Page 54: Developing Software that Matters II

54http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

// 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 55: Developing Software that Matters II

55http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

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

if signal = CLEAR thenincrease_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 56: Developing Software that Matters II

56http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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);…

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

Page 57: Developing Software that Matters II

57http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Defects in the Previous Codevoid 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

► You can use any integer value or object instead of an enum Alert_Type which in most cases will be an error

Page 58: Developing Software that Matters II

58http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

► 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 59: Developing Software that Matters II

59http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 60: Developing Software that Matters II

60http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 61: Developing Software that Matters II

61http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

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

Page 62: Developing Software that Matters II

62http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Enumeration Types in Ada

► Enumerations are true types in Ada not an integer like in C or C++� Java does not have enumerations so you must use integers

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

procedure P (B : Integer) isA : Alert_Type;

beginA := B;…

Compilation errorCompilation error

// Javapublic static final int LOW = 0;public static final int MEDIUM = 0;public static final int HIGH = 0;public static final int VERY_HIGH = 0;

Page 63: Developing Software that Matters II

63http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Enumeration Types and Attributes

VERY_HIGHAlert_Type ' Last

LOWAlert_Type ' First

Page 64: Developing Software that Matters II

64http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Predefined Enumerations in Ada

type BooleanBoolean is (False, True);

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

Page 65: Developing Software that Matters II

65http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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_Arithmetic_Operator (C : Character) return Boolean isbegin

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

return True;when others =>

return False;end case;

end Is_Arithmetic_Operator;

Page 66: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Conciseness Versus Readability

Page 67: Developing Software that Matters II

67http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Always Favor Readability

► What does the following mean:� This is valid C/C++/Java� It is very concise �� � but not very readable

► What does the following mean:� This is valid Ada� It is less concise �� � but very readable

int x;int y;int z;…x = y---z--;

x : integer;y : integer;z : integer;…x := y - z;y := y - 1;z := z - 1;

Page 68: Developing Software that Matters II

68http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Conciseness and Non Determinism

► What does the following mean:� It compiles fine, but �� � Its semantics are undetermined

► It could mean any one of the following (when written in Ada)

int k;int v [10];…k = v [k++];

K : Integer;V : array (0 .. 9) of Integer;…K := V (K);

K : Integer;V : array (0 .. 9) of Integer;…K := V (K);K := K + 1;

Page 69: Developing Software that Matters II

69http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

C/C++ Conciseness is Not So Concise and It Can Be Inefficient

► What's the problem with this C/C++ typical code sequence?� It's inefficient on processors with specific string handling instructions

► Ada version is shorter and more efficient

char s1 [10];char s2 [10];…while (*s1++ = *s2++);

S1 : String (1 .. 10);S2 : String (1 .. 10);…S1 := S2;

Page 70: Developing Software that Matters II

70http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

If Anybody Can't Read It Don't Write It

► A piece of code is written once ….

► … but read and modified many many times

► C/C++/Java syntax favors conciseness over readability� This leads to bugs and lots of wasted time in debugging� This means that software is more costly to develop or is buggy or both

► Ada syntax favors readability� Ada compiler catches silly mistakes� Faster and cheaper to produce correct code when written in Ada

Page 71: Developing Software that Matters II

71http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Coding Conventions and Readability

► Use coding conventions favoring readability► Typical C++ and Java coding conventions hamper readability

void thisFunctionNameIsHardToRead ();

void This_Function_Name_Is_Easy_To_Read ();

Page 72: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

C/C++/Java Type System

Page 73: Developing Software that Matters II

73http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 74: Developing Software that Matters II

74http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 75: Developing Software that Matters II

75http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Objects, Variables and Constants

► An object of a given type is a run-time entity (usually a piece of memory) containing values of the type

► A variable is an object whose value can change

► A constant is an object whose value cannot change after it has been initialized

Page 76: Developing Software that Matters II

76http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Example

int w;ww

memorymemory

► int is a pre-defined integer type in C whose values go from INT_MIN to INT_MAX

► Some of the predefined operations that can be applied to int are:� Addition, subtraction, multiplication, division, module, etc.

An object with name wThe object is a variable

Page 77: Developing Software that Matters II

77http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Type Checking

► Type checking is the process that checks that programs conform to the typing rules of the language

► Type checking can be performed� Statically at compile-time� Dynamically at execution-time

► A language is strongly typed if it prohibits � The application of an operation to an object that is not intended to

support the operation (assignment is considered an operation)

► A language is weakly typed if it is not strongly typed

Page 78: Developing Software that Matters II

78http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Strong Typing is Good

► It guarantees a program will not crash

► It tells the programmer when she has mixed "apples" with "oranges"

Page 79: Developing Software that Matters II

79http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Some Examples

► Strongly (mainly statically) typed languages:� Ada, Eiffel, Java

► Strongly dynamically typed languages� Lisp, Smalltalk

► Weakly typed languages� C, C++

► Completely untyped languages� assembly languages, shell scripts

Page 80: Developing Software that Matters II

80http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Typing Problems Common to C/C++/Java

► No user-defined types for� Scalars (characters, integers, reals)� Pointers� Arrays

► Implicit conversions from integers to reals► Weak overflow semantics rules for integers types► Missing types

� Enumerations� Character types in C/C++� Fixed points� Unsigned integers in Java� Pointers to functions in Java

Page 81: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

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

No User-Defined Scalar Types

Page 82: Developing Software that Matters II

82http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

C/C++ Example

► The program to the left compiles fine …

► … But 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);

}

Page 83: Developing Software that Matters II

83http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Bugs can have Disastrous Consequences

Page 84: Developing Software that Matters II

84http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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);

}

Page 85: Developing Software that Matters II

85http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 indistinguishible 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);

}

Page 86: Developing Software that Matters II

86http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 87: Developing Software that Matters II

87http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 88: Developing Software that Matters II

88http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 89: Developing Software that Matters II

89http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;…

Compilation errorCompilation error

Compilation errorCompilation error

Page 90: Developing Software that Matters II

90http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Ada is Strongly Typed (2 of 2)

► Parameter 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;Compilation errorCompilation error

Page 91: Developing Software that Matters II

91http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 92: Developing Software that Matters II

92http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 93: Developing Software that Matters II

93http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Named parameterNamed parameter

Page 94: Developing Software that Matters II

94http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Avoiding Parameter Confusion in Ada

Summary: Two lines of defense

► User defined types

► Named parameters

Page 95: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

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

Integer Overflow Semantics

Page 96: Developing Software that Matters II

96http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;}

Page 97: Developing Software that Matters II

97http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;Exception raised Exception raised at execution timeat execution time

Page 98: Developing Software that Matters II

98http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Example: Overflow in Action in Ada

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

Page 99: Developing Software that Matters II

99http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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);

}

Page 100: Developing Software that Matters II

100http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Infinite Loop when last_byte == 127

Two problems:

1. Wrap around semantics of type byte� When last_byte = b = 127 we execute the loop, we do b++ and b

wraps to -128

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

Meansx; while (y) { �; z; }

Page 101: Developing Software that Matters II

101http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 102: Developing Software that Matters II

102http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 103: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Side Notes on Ada Types

Page 104: Developing Software that Matters II

104http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 105: Developing Software that Matters II

105http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 106: Developing Software that Matters II

106http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Predefined Ada Subtypes

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

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

Page 107: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Exceptions in Ada

Page 108: Developing Software that Matters II

108http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

When a Check Fails an Exception is Raised in Ada

Page 109: Developing Software that Matters II

109http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Ada Predefined Exceptions

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

► Constraint_Error: integer overflow, computation error (divide by zero), array index out of range, null pointer dereferencing, …

► Storage_Error: no more memory available

► Program_Error: fundamental program error (e.g. end of function with no return statement)

Page 110: Developing Software that Matters II

110http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 111: Developing Software that Matters II

111http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

11

22

ExceptionExceptionraisedraised33

Page 112: Developing Software that Matters II

112http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Page 113: Developing Software that Matters II

113http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Exception HandlerException Handler

Page 114: Developing Software that Matters II

114http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

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

Page 115: Developing Software that Matters II

115http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What Happens at Execution Timewith 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 116: Developing Software that Matters II

116http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 117: Developing Software that Matters II

117http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 118: Developing Software that Matters II

118http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 119: Developing Software that Matters II

119http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

procedure Calc (A, B : Float) isC, D : Float;

begin…declare

Old_C : Float := C;begin

C := A * B;D := C ** 2;

exceptionwhen Constraint_Error =>

C := Old_C;D := 0.0;

end;…

end Calc;

Example of a Declare Block

Page 120: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Array Pitfalls in C

Page 121: Developing Software that Matters II

121http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Arrays in C

► No real arrays in C► An array is just a pointer to a chunk of memory

#include <stdio.h>

int main () {char *str = "bugy";

printf ("%c\n", 0 [str]);printf ("%c\n", * (str+1));printf ("%c\n", * (2+str));printf ("%c\n", str [3]);

}

Page 122: Developing Software that Matters II

122http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

C "Arrays" are Just Pointers: No Safety

#include <stdio.h>#include <string.h>

char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;memcpy (p, "0123456789", 10);display ();x [6]= '?';display ();

}

void display_arr (char *name, char *arr, int n) {int k;printf ("%s = ", name);for (k = 0; k < n; k++)

printf ("%c", arr [k]);printf ("\n");

}

void display () {display_arr ("x", x, 4);display_arr ("y", y, 4);display_arr ("z", z, 4);printf ("------------\n");

}

Page 123: Developing Software that Matters II

123http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What Does the C Standard Say?…char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;

memcpy (p, "0123456789", 10);display ();

x [6]= '?';display ();

}

Result is undefined since x is a Result is undefined since x is a pointer that points to 4 pointer that points to 4 consecutrive consecutrive preallocated preallocated bytes in memory, not 7 bytes in memory, not 7 compiler is free to do what it wantscompiler is free to do what it wants

Set p to the address of x Set p to the address of x

Copy "0123456789" in the Copy "0123456789" in the 10 consecutive memory 10 consecutive memory locations pointed by p locations pointed by p

Page 124: Developing Software that Matters II

124http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What Happens in Practice

Page 125: Developing Software that Matters II

125http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What Happens in Memory: Allocation

#include <stdio.h>#include <string.h>

char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;memcpy (p, "0123456789", 10);display ();x [6]= '?';display ();

}

JJIIEEDDCCBBAA LLKKHHGGFFz[0]z[0]y[1]x[3]x[2]x[1]x[0] z[3]z[2]y[4]y[3]y[2]

Page 126: Developing Software that Matters II

126http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Pointer Copy

#include <stdio.h>#include <string.h>

char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;memcpy (p, "0123456789", 10);display ();x [6]= '?';display ();

}

JJIIEEDDCCBBAA LLKKHHGGFFz[0]z[0]y[1]x[3]x[2]x[1]x[0] z[3]z[2]y[4]y[3]y[2]

p

Page 127: Developing Software that Matters II

127http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

memcpy

#include <stdio.h>#include <string.h>

char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;memcpy (p, "01234567890123456789", 10);display ();x [6]= '?';display ();

}

99884433221100 LLKK776655z[0]z[0]y[1]x[3]x[2]x[1]x[0] z[3]z[2]y[4]y[3]y[2]

p

Page 128: Developing Software that Matters II

128http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

x[6] = '?'

#include <stdio.h>#include <string.h>

char x [4] = {'A', 'B', 'C', 'D'};char y [4] = {'E', 'F', 'G', 'H'};char z [4] = {'I', 'J', 'K', 'L'};…int main () {

char *p;

display();p = x;memcpy (p, "0123456789", 10);display ();x [6]= '?';display ();

}

99884433221100 LLKK77??55z[0]z[0]y[1]x[3]x[2]x[1]x[0] z[3]z[2]y[4]y[3]y[2]

p

Page 129: Developing Software that Matters II

129http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

C and Arrays: Summary

► No real arrays

► Very low level

► Fundamentally unsafe mechanism

► Too many ways of expressing the same thing

Page 130: Developing Software that Matters II

130http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

What about C++ and Java

► C++� Same problem as in C� You can redefine the "[ ]" operator in C++ thereby providing your own

checks and semantics. However this makes code hard to read sincewhen you see something like s [k] it does not mean any more what you've been used to by many years of C and makes the code very hard to understand

► Java� Has real arrays� Java model inspired from Ada� Difference between Java and Ada is that Java arrays MUST start at

index 0, Ada can have arbitrary bounds

Page 131: Developing Software that Matters II

131http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Arrays in Ada

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

► Ada array can have its initial size determined at run-time

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

Page 132: Developing Software that Matters II

132http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;

Page 133: Developing Software that Matters II

133http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 134: Developing Software that Matters II

134http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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;Exception raisedException raised

Page 135: Developing Software that Matters II

135http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Example of 1-Dim Array Attributes

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

90A ' Length

99A ' Last

10 .. 99A ' Range

10A ' First

Page 136: Developing Software that Matters II

136http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

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

beginfor K in V ’ Range loop

if V (K) > M thenM := 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 137: Developing Software that Matters II

137http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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"

Page 138: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Records and Pointers in Ada

Page 139: Developing Software that Matters II

139http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Record Types

type Date is recordDay : 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 140: Developing Software that Matters II

140http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

type Node;type Node_Ptr is access Node;

type Node is recordD : Date := (1, 1, 1900);Next : Node_Ptr;

end record;

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

Memory

11

1900null

39

1975

Pointers and Records

Page 141: Developing Software that Matters II

141http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

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

Memory

3112

1999null

Page 142: Developing Software that Matters II

142http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Accessing Record Fields: A Simple Rule

If P is a pointer to a record thenP.all points to the WHOLE recordP.Field points to Field in the record

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

type Node is recordD : 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 143: Developing Software that Matters II

143http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Parametrized Records: Discriminantstype Q_Array (Positive range <>) of Integer;

type Queue (Max_Size : Positive) is recordFirst : 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 144: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Parameter Passing in C, Java and Ada

Page 145: Developing Software that Matters II

145http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Two Parameter Passing Modes in C/Java

► By value

► By constant value� In Java this is a real mode, in C it is just a suggestion �

► In C++ there are additional modes� By reference� By constant reference

Page 146: Developing Software that Matters II

146http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

By Value

► The parameter can be changed inside the function but the value of the original parameter is not modified

void copy (int x, int y) {x = y;

}

void try () {int a = 0;int b = 9;copy (a, b);

// a == 0 here}

Page 147: Developing Software that Matters II

147http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

By Constant Value

► In C� Indication to the compiler that the parameter will not be changed

inside the function. If the function does, that's fine�� One would hope that a reasonable compiler would at least emit a

warning ...

► In Java

void copy (const int x, const int y) {x = y;

} Warning with GCCWarning with GCC

void copy (final int x, final int y) {x = y;

} Compilation error in JavaCompilation error in Java

Page 148: Developing Software that Matters II

148http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Changing the Actual Parameter► In Java

� There is NO way to change the value of a scalar parameter- You have to do it yourself by hand �

� For a record (class) or array parameter you can only change the components

� This is a problem: Java really makes the programmer's life hard here

► In C� You have to create a pointer by hand and use that� The programmer must perform tedious bookkeeping by specifying

- *p and &s� This also makes the code hard to change

void foo (int *p);…int s;foo (& s);

Page 149: Developing Software that Matters II

149http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Three Parameter Passing Modes in Ada

function Log (X : Float) return Float;function Log (X : in Float) return 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

procedure Copy (Y : Float; X : 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 Increment (X : in out Float);

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 in

procedure Open_File (X : String);procedure Open_File (X : in String);

Page 150: Developing Software that Matters II

150http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Example: Mode "in"

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

Page 151: Developing Software that Matters II

151http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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

Page 152: Developing Software that Matters II

152http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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 153: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

C/C++/Java are not good low level programming languages

Page 154: Developing Software that Matters II

154http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Representation Clauses

Page 155: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Interfacing Ada with C

Page 156: Developing Software that Matters II

© ACT Europe under the GNU Free Documentation License

Summary: Better Safe than Sorry

Page 157: Developing Software that Matters II

157http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

Language Safety and Security

C++ C Java Adaunsafe safeassembly

Page 158: Developing Software that Matters II

158http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License

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


Recommended