developing software that matters ii
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 problemsTRANSCRIPT
© 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
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
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
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)
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
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.
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
8http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Programming in the Large:Abstraction & Structure
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;...
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
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
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/
© ACT Europe under the GNU Free Documentation License
C/C++ Consistency Problems
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?
15http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
The Program Crashes. Why?
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
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
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
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
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
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
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
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
© ACT Europe under the GNU Free Documentation License
Notes on the Ada Example
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;
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;
© ACT Europe under the GNU Free Documentation License
Structure of an Ada Program
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 �;
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;
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
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
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
© ACT Europe under the GNU Free Documentation License
C/C++/Java Numeric Pitfall
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?
35http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Surprised ?
Was this the programmer’s intent ?
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
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
© ACT Europe under the GNU Free Documentation License
Some C/C++ Lexical & Syntactic Pitfalls
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?
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...
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
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
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
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"
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
© ACT Europe under the GNU Free Documentation License
Side Note on Ada Attributes
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
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)
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
© ACT Europe under the GNU Free Documentation License
More C/C++/Java Syntactic Pitfalls
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;}
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?
53http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Bugs can Have Serious Consequences
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
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
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?
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
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
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;
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;
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
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;
63http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Enumeration Types and Attributes
VERY_HIGHAlert_Type ' Last
LOWAlert_Type ' First
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', …);
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;
© ACT Europe under the GNU Free Documentation License
Conciseness Versus Readability
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;
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;
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;
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
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 ();
© ACT Europe under the GNU Free Documentation License
C/C++/Java Type System
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
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
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
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
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
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"
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
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
© ACT Europe under the GNU Free Documentation License
Example of C/C++/Java Type System Weakness
No User-Defined Scalar Types
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);
}
83http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Bugs can have Disastrous Consequences
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);
}
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);
}
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;
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;
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;
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
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
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;
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;
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
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
© ACT Europe under the GNU Free Documentation License
Example of C/C++/Java Type System Weakness
Integer Overflow Semantics
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;}
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
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
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);
}
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; }
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;
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
© ACT Europe under the GNU Free Documentation License
Side Notes on Ada Types
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;
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;
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;
© ACT Europe under the GNU Free Documentation License
Exceptions in Ada
108http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
When a Check Fails an Exception is Raised in Ada
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)
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;
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
112http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
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
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
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
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;
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;
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
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
© ACT Europe under the GNU Free Documentation License
Array Pitfalls in C
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]);
}
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");
}
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
124http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
What Happens in Practice
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]
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
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
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
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
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
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
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;
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
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
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
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
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"
© ACT Europe under the GNU Free Documentation License
Records and Pointers in Ada
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;
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
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
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;
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
© ACT Europe under the GNU Free Documentation License
Parameter Passing in C, Java and Ada
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
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}
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
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);
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);
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
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
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"
© ACT Europe under the GNU Free Documentation License
C/C++/Java are not good low level programming languages
154http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Representation Clauses
© ACT Europe under the GNU Free Documentation License
Interfacing Ada with C
© ACT Europe under the GNU Free Documentation License
Summary: Better Safe than Sorry
157http://libre.act-europe.fr © ACT Europe under the GNU Free Documentation License
Language Safety and Security
C++ C Java Adaunsafe safeassembly
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