• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Developing Software that Matters II
 

Developing Software that Matters II

on

  • 1,902 views

Author: ACT Europe. ...

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

Statistics

Views

Total Views
1,902
Views on SlideShare
1,902
Embed Views
0

Actions

Likes
3
Downloads
86
Comments
3

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

13 of 3 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • It is illuminating to see that how much java took ideas from Ada.
    Are you sure you want to
    Your message goes here
    Processing…
  • Ada rules actually but people do not use this wonderfull tool.
    Are you sure you want to
    Your message goes here
    Processing…
  • I love Ada.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Developing Software that Matters II Developing Software that Matters II Presentation Transcript

    • Programming in the Small: Common C/C++/Java Pitfalls & How Ada Avoids them Franco Gasperoni gasperon@act-europe.fr http://libre.act-europe.fr/Software_Matters © 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 http://libre.act-europe.fr 2 © 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 http://libre.act-europe.fr 3 © 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) http://libre.act-europe.fr 4 © 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 http://libre.act-europe.fr 5 © 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. http://libre.act-europe.fr 6 © ACT Europe under the GNU Free Documentation License
    • Programming: Abstraction, Structure & Coding Detail Uses the services of Structuring element: Module, package, class, file, … http://libre.act-europe.fr 7 © ACT Europe under the GNU Free Documentation License
    • Programming in the Large: Abstraction & Structure http://libre.act-europe.fr 8 © 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; . . . http://libre.act-europe.fr 9 © 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 http://libre.act-europe.fr 10 © ACT Europe under the GNU Free Documentation License
    • Important Note ► All C/C++/Java code examples showed in this lecture compile • They are quot;correctquot; 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 http://libre.act-europe.fr 11 © 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/ http://libre.act-europe.fr 12 © ACT Europe under the GNU Free Documentation License
    • C/C++ Consistency Problems © ACT Europe under the GNU Free Documentation License
    • What is the Program Output ? int main () { ► This program compiles fine int length = 8265; int width = 0252; ► What is its output? int height = 8292; printf (length); printf (width); printf (height); } http://libre.act-europe.fr 14 © ACT Europe under the GNU Free Documentation License
    • The Program Crashes. Why? http://libre.act-europe.fr 15 © ACT Europe under the GNU Free Documentation License
    • Where does printf() Come From? int main () { int length = 8265; int width = 0252; int height = 8292; printf (length); printf (width); printf (height); } ► 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 http://libre.act-europe.fr 16 © ACT Europe under the GNU Free Documentation License
    • The Ada Version with Text_IO; procedure Main is Length : Integer := 8265; Width : Integer := 0252; Height : Integer := 8292; begin Text_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 http://libre.act-europe.fr 17 © ACT Europe under the GNU Free Documentation License
    • Procedure Main ► Procedure Main • Stored in file main.adb • Technically this is called a compilation unit with Text_IO; ► A compilation unit can be the body or the spec (specification) of a: procedure Main is • procedure Length : Integer := 8265; • function Width : Integer := 0252; Height : Integer := 8292; • package (see next lecture) begin ► Spec = precise list of services exported Text_IO . Put_Line (Length'img); ► Body = implementation details Text_IO . Put_Line (Width'img); ► In GNAT: Text_IO . Put_Line (Height'img); • 1 compilation unit per file end Main; • File name matches unit name • 2 file extensions possible - .adb = Ada Body - .ads = Ada Spec Note: Ada is case insensitive http://libre.act-europe.fr 18 © ACT Europe under the GNU Free Documentation License
    • Inside Procedure Main with Text_IO; procedure Main is ► Declarative part: Contains the declaration of: Length : Integer := 8265; • Variable, types, nested procedures, nested Width : Integer := 0252; functions, ... used in procedure Main Height : Integer := 8292; begin ► Procedure statements Text_IO . Put_Line (Length'img); Text_IO . Put_Line (Width'img); Text_IO . Put_Line (Height'img); end Main; http://libre.act-europe.fr 19 © ACT Europe under the GNU Free Documentation License
    • with Text_IO; ► List of compilation units whose services are used in procedure Main with Text_IO; ► Text_IO is the predefined Ada text procedure Main is Input/Output library Length : Integer := 8265; Width : Integer := 0252; Height : Integer := 8292; begin ► Procedures declared in library Text_IO and Text_IO . Put_Line (Length'img); used in Main Text_IO . Put_Line (Width'img); Text_IO . Put_Line (Height'img); end Main; http://libre.act-europe.fr 20 © ACT Europe under the GNU Free Documentation License
    • Ada Guarantees Consistency ► Compiler • Checks that you quot;withquot; 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 http://libre.act-europe.fr 21 © ACT Europe under the GNU Free Documentation License
    • C Does not Guarantee Consistency ► Check all the warnings ► You can improve the situation as follows: ► If you are not sure which objects you are linking delete all objects ► Always #include the headers of and recompile everything before the files whose services your are linking using ► There are additional tricks http://libre.act-europe.fr 22 © 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 http://libre.act-europe.fr 23 © ACT Europe under the GNU Free Documentation License
    • Notes on the Ada Example © 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 Main with Text_IO; use Text_IO; procedure Main is Length : Integer := 8265; Width : Integer := 0252; Height : Integer := 8292; begin Text_IO . Put_Line (Length'img); Text_IO . Put_Line (Width'img); Text_IO . Put_Line (Height'img); end Main; http://libre.act-europe.fr 25 © ACT Europe under the GNU Free Documentation License
    • The ' img Attribute with Text_IO; use Text_IO; procedure Main is Length : Integer := 8265; Width : Integer := 0252; Height : Integer := 8292; begin ► ' img is a predefined attribute Text_IO . Put_Line (Length ' img); • Given an integer or floating point number X, Text_IO . Put_Line (Width ' img); X ' img returns its string representation Text_IO . Put_Line (Height ' img); • More on attributes later on end Main; http://libre.act-europe.fr 26 © ACT Europe under the GNU Free Documentation License
    • Structure of an Ada Program © ACT Europe under the GNU Free Documentation License
    • General Structure of an Ada Program with …; with …; with …; with …; with …; with …; procedure Some_Main is … begin … end Some_Main; http://libre.act-europe.fr 28 © ACT Europe under the GNU Free Documentation License
    • A Simple Example with Text_IO; use Text_IO; function Fact (N : Integer) return Integer is procedure Display (S : String; X, Y : Integer) is begin begin if N <= 1 then Put_Line (S & quot; (quot; & X'img & quot;) = quot; & Y'img); return 1; end Display; else return N * Fact (N - 1); end if; end Fact; with Display; with Fact; procedure Display_Fact is begin for K in 1 .. 4 loop Display (quot;Factorialquot;, K, Fact (K)); end loop; end Display_Fact; http://libre.act-europe.fr 29 © ACT Europe under the GNU Free Documentation License
    • Building & Executing Display_Fact ► GNAT has an automatic quot;makequot; 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 http://libre.act-europe.fr 30 © 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) is begin Put_Line (S & quot; (quot; & X'img & quot;) = quot; & Y'img); end Display; & = 1 2 3 4 5 A B 1 2 3 4 5 A B 1 dimensional arrays http://libre.act-europe.fr 31 © ACT Europe under the GNU Free Documentation License
    • Note on For Loops ► In for loops, the loop variable (K with Display; in the example) is implicitely with Fact; declared procedure Display_Fact is begin for K in 1 .. 4 loop ► The loop variable cannot be Display (quot;Factorialquot;, K, Fact (K)); modified inside the for loop end loop; end Display_Fact; ► The loop variable ceases to exist just after the loop http://libre.act-europe.fr 32 © ACT Europe under the GNU Free Documentation License
    • C/C++/Java Numeric Pitfall © ACT Europe under the GNU Free Documentation License
    • What is the Program Output ? #include <stdio.h> ► This program compiles fine int main () { ► What is its output? int length = 8265; int width = 0252; int height = 8292; printf (quot;length = %dnquot;, length); printf (quot;width = %dnquot;, width); printf (quot;height = %dnquot;, height); } http://libre.act-europe.fr 34 © ACT Europe under the GNU Free Documentation License
    • Surprised ? Was this the programmer’s intent ? http://libre.act-europe.fr 35 © 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 http://libre.act-europe.fr 36 © ACT Europe under the GNU Free Documentation License
    • Numbers in Ada Length : Integer := 8265; Width : Integer := 0252; -- regular decimal number Width_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 ► 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 http://libre.act-europe.fr 37 © ACT Europe under the GNU Free Documentation License
    • Some C/C++ Lexical & Syntactic Pitfalls © ACT Europe under the GNU Free Documentation License
    • Is the Following Code Correct ? #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++; } ► This program compiles fine, but has a number of problems. Which ones? http://libre.act-europe.fr 39 © 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... http://libre.act-europe.fr 40 © ACT Europe under the GNU Free Documentation License
    • What about Java? ► = versus == • This problem exists in Java for boolean, boolean safety_flag; boolean danger_flag; but has been fixed for other data types … if (safety_flag = danger_flag) { ► Dangling else problem sound_alarm (); } • Problem is still there This is OK in Java ► Bad comment but is often a bug • Problem is still there ► Bad operator precedence *j++ means *(j++) • No * operator in Java. This Problem has been solved http://libre.act-europe.fr 41 © ACT Europe under the GNU Free Documentation License
    • The Correct Version #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)++; } } http://libre.act-europe.fr 42 © ACT Europe under the GNU Free Documentation License
    • Ada Solves all the Previous Pitfalls -- 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) is begin if Y = 0 then if X > 0 then K := Integer’Last; -- K is set to the largest Integer end if; else K := X / Y; -- it is safe to divide by Y since it cannot be 0 Y := Y + 1; end if; end Check_Divide; http://libre.act-europe.fr 43 © ACT Europe under the GNU Free Documentation License
    • Simpler Ada Version: quot;elsifquot; quot;and thenquot; -- 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) is begin if Y = 0 and then X > 0 then K := Integer’Last; -- K is set to the largest Integer elsif Y /= 0 then K := X / Y; -- it is safe to divide by Y since it cannot be 0 Y := Y + 1; end if; end Check_Divide; http://libre.act-europe.fr 44 © 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 http://libre.act-europe.fr 45 © ACT Europe under the GNU Free Documentation License
    • Side Note on Ada Attributes © 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 http://libre.act-europe.fr 47 © 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 T ' First Smallest value in T T ' Last Largest value in T T ' image (X) String representation of X In GNAT you can use X ' img instead of T ' image (X) http://libre.act-europe.fr 48 © ACT Europe under the GNU Free Documentation License
    • Example of Integer ' Last procedure Check_Divide_And_Increment (K : in out Integer; I : Integer; J : in out Integer) is begin if Y = 0 then if X > 0 then K := Integer’Last; -- K is set to the largest Integer end if; else K = X / Y; -- it is safe to divide by Y since it cannot be 0 end if; Y := Y + 1; end Checked_Divide; http://libre.act-europe.fr 49 © ACT Europe under the GNU Free Documentation License
    • More C/C++/Java Syntactic Pitfalls © ACT Europe under the GNU Free Documentation License
    • Case Sensitivity Is Error-Prone // In file1 // In file2 int totalLength = 0; int totallength = 0; // In file3 void addLength (int length) { totallength += length; } ► 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 http://libre.act-europe.fr 51 © ACT Europe under the GNU Free Documentation License
    • Is the Following Code Correct ? // If the signal ahead is clear then increase the speed. void increase_speed_if_safe (int speed, int signal) { if (signal == CLEAR); increase_speed (); } ► This program compiles fine, but has a problem. Which one? http://libre.act-europe.fr 52 © ACT Europe under the GNU Free Documentation License
    • Bugs can Have Serious Consequences http://libre.act-europe.fr 53 © ACT Europe under the GNU Free Documentation License
    • Be Careful of Spurious Semicolons // If the signal ahead is clear then increase the speed. void increase_speed_if_safe (int speed, int signal) { if (signal == CLEAR); increase_speed (); } http://libre.act-europe.fr 54 © ACT Europe under the GNU Free Documentation License
    • The Ada Version is Always Safe -- If the signal ahead is clear then increase the speed. procedure increase_speed_if_safe (speed : integer; signal : integer) is begin if signal = CLEAR then increase_speed; end if; end increase_speed_if_safe; ► If you write if signal = CLEAR then ; • You get a compiler error http://libre.act-europe.fr 55 © 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? http://libre.act-europe.fr 56 © ACT Europe under the GNU Free Documentation License
    • Defects in the Previous Code void handle_alert (enum Alert_Type alert) { switch (alert) { case LOW: ► Don't forget break statements activate_camera (); break; case MEDIUM: ► C/C++/Java do not check that you send_guard (); have treated all cases in the switch break; case HIGH: ► You can use any integer value or sound_alarm (); object instead of an enum Alert_Type break; case VERY_HIGH: which in most cases will be an error alert_police (); break; } } void process_alerts () { handle_alert (HIGH); http://libre.act-europe.fr 57 © ACT Europe under the GNU Free Documentation License
    • Ada is Safer (and Less Verbose) type Alert_Type is (LOW, MEDIUM, HIGH, VERY_HIGH); ► No break statements procedure Process_Alert (Alert : Alert_Type) is ► Ada will check that you begin have treated all cases in case Alert is the case statement when LOW => Activate_Camera; when MEDIUM => ► You can only use an object Send_Guard; of type Alert_Type when HIGH => Sound_Alarm; when VERY_HIGH => Alert_Police; end case; end Process_Alert; http://libre.act-europe.fr 58 © ACT Europe under the GNU Free Documentation License
    • Combining Cases procedure Process_Alert (Alert : Alert_Type) is begin case Alert is when LOW => Activate_Camera; when MEDIUM => Send_Guard; when HIGH | VERY_HIGH => Sound_Alarm; Alert_Police; end case; end Process_Alert; http://libre.act-europe.fr 59 © ACT Europe under the GNU Free Documentation License
    • Using a Default Clause procedure Process_Alert (Alert : Alert_Type) is begin case Alert is when LOW => Activate_Camera; when MEDIUM => Send_Guard; when others => Sound_Alarm; Alert_Police; end case; end Process_Alert; http://libre.act-europe.fr 60 © ACT Europe under the GNU Free Documentation License
    • Using a Range procedure Process_Alert (Alert : Alert_Type) is begin case Alert is when 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 http://libre.act-europe.fr 61 © ACT Europe under the GNU Free Documentation License
    • Enumeration Types in Ada type Alert_Types is (LOW, MEDIUM, HIGH, VERY_HIGH); procedure P (B : Integer) is A : Alert_Type; begin Compilation error A := B; … ► Enumerations are true types in Ada not an integer like in C or C++ • Java does not have enumerations so you must use integers // Java public static final int LOW = 0; public static final int MEDIUM = 0; public static final int HIGH = 0; public static final int VERY_HIGH = 0; http://libre.act-europe.fr 62 © ACT Europe under the GNU Free Documentation License
    • Enumeration Types and Attributes Alert_Type ' First LOW Alert_Type ' Last VERY_HIGH http://libre.act-europe.fr 63 © ACT Europe under the GNU Free Documentation License
    • Predefined Enumerations in Ada type Boolean is (False, True); type Character is (…, 'a', 'b', 'c', …); http://libre.act-europe.fr 64 © ACT Europe under the GNU Free Documentation License
    • Predefined Enumerations: Examples function Is_Letter (C : Character) return Boolean is begin return (C in 'a' .. 'z') or (C in 'A' .. 'Z'); end Is_Letter; function Is_Arithmetic_Operator (C : Character) return Boolean is begin case C is when '+' | '-' | '*' | '/' => return True; when others => return False; end case; end Is_Arithmetic_Operator; http://libre.act-europe.fr 65 © ACT Europe under the GNU Free Documentation License
    • Conciseness Versus Readability © ACT Europe under the GNU Free Documentation License
    • Always Favor Readability ► What does the following mean: int x; int y; • This is valid C/C++/Java int z; • It is very concise … … • … but not very readable x = y---z--; ► What does the following mean: x : integer; • This is valid Ada y : integer; z : integer; • It is less concise … … • … but very readable x := y - z; y := y - 1; z := z - 1; http://libre.act-europe.fr 67 © ACT Europe under the GNU Free Documentation License
    • Conciseness and Non Determinism ► What does the following mean: int k; • It compiles fine, but … int v [10]; • … Its semantics are undetermined … k = v [k++]; ► It could mean any one of the following (when written in Ada) K : Integer; K : Integer; V : array (0 .. 9) of Integer; V : array (0 .. 9) of Integer; … … K := V (K); K := V (K); K := K + 1; http://libre.act-europe.fr 68 © 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 char s1 [10]; char s2 [10]; … while (*s1++ = *s2++); ► Ada version is shorter and more efficient S1 : String (1 .. 10); S2 : String (1 .. 10); … S1 := S2; http://libre.act-europe.fr 69 © 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 http://libre.act-europe.fr 70 © 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 (); http://libre.act-europe.fr 71 © ACT Europe under the GNU Free Documentation License
    • C/C++/Java Type System © 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 http://libre.act-europe.fr 73 © 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 http://libre.act-europe.fr 74 © 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 http://libre.act-europe.fr 75 © ACT Europe under the GNU Free Documentation License
    • Example An object with name w The object is a variable memory int w; w ► 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. http://libre.act-europe.fr 76 © 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 http://libre.act-europe.fr 77 © 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 quot;applesquot; with quot;orangesquot; http://libre.act-europe.fr 78 © 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 http://libre.act-europe.fr 79 © 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 http://libre.act-europe.fr 80 © ACT Europe under the GNU Free Documentation License
    • Example of C/C++/Java Type System Weakness No User-Defined Scalar Types © ACT Europe under the GNU Free Documentation License
    • C/C++ Example typedef int Time; ► The program to the left compiles typedef int Distance; fine … typedef int Speed; … const Speed SAFETY_SPEED = 120; ► … But there is something wrong … with it. What ? 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); } http://libre.act-europe.fr 82 © ACT Europe under the GNU Free Documentation License
    • Bugs can have Disastrous Consequences http://libre.act-europe.fr 83 © ACT Europe under the GNU Free Documentation License
    • What's Wrong with C/C++ typedef int Time; ► Program compiles fine but has 2 typedef int Distance; serious flaws that go undetected typedef int Speed; ► FLAW 1: … const Speed SAFETY_SPEED = 120; • t is a Time … • increase_speed() takes a Speed void increase_speed (Speed s); parameter … • Time and Speed are conceptually void check_speed (Time t, Distance d) { different, they should not be mixed up Speed s = d/t; ► FLAW 2: if (s < SAFETY_SPEED) increase_speed (t); • Distance and Time parameters have } been inverted void perform_safety_checks () { • Time and Distance are conceptually Time t = get_time (); different, they should not be mixed up Distance d = get_distance (); ► C/C++ provide NO HELP to the … programmer in detecting these check_speed (d, t); mistakes } http://libre.act-europe.fr 84 © ACT Europe under the GNU Free Documentation License
    • Things are Even Worse in Java ► There are no typedef in Java final int SAFETY_SPEED = 120; … ► Everything must be an int void check_speed (int t, int d) { int s = d/t; ► typedef are useful for documentation if (s < SAFETY_SPEED) purposes increase_speed (t); } ► typedef could be used to perform sanity void increase_speed (int s) { … } checks during code walkthroughs or void perform_safety_checks () { with simple tools int t = get_time (); int d = get_distance (); ► This problem is particularly severe in … check_speed (d, t); Java given that many API calls have } several indistinguishible int parameters: • AdjustmentEvent (Adjustable source, int id, int type, int value) http://libre.act-europe.fr 85 © ACT Europe under the GNU Free Documentation License
    • What About Ada? -- Buggy code. DON'T write this ► You can write the same buggy code in Ada, but … SAFETY_SPEED : constant Integer := 120; … procedure Increase_Speed (S : Integer); … ► … Ada has two lines of defense procedure Check_Speed (T : Integer; D : Integer) is S : Integer := D / T; that do not exist in C/C++ or begin if S < SAFETY_SPEED then Java to protect the programmer Increase_Speed (T); end if; • User defined types end Check_Speed; • Parameter associations procedure Perform_Safety_Checks is T : Integer := Get_Time; D : Integer := Get_Distance; begin … Check_Speed (D, T); end Perform_Safety_Checks; http://libre.act-europe.fr 86 © 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; http://libre.act-europe.fr 87 © ACT Europe under the GNU Free Documentation License
    • User Defined Integer Types in Ada ► Each user defined integer type introduces a new type type Time is range 0 .. 3_600; ► This new type is NOT a synonym of Integer type Distance is range 0 .. 1_000; ► Each user defined integer type gives its type Speed is range 0 .. 4_000; bounds, i.e. the values any object of this type can take • Time ' First = 0 • Time ' Last = 3_600 http://libre.act-europe.fr 88 © ACT Europe under the GNU Free Documentation License
    • Ada is Strongly Typed (1 of 2) ► When you define the proper types type Time is range 0 .. 3_600; the Ada compiler catches the errors type Distance is range 0 .. 1_000; type Speed is range 0 .. 4_000; ► To mix different types you must SAFETY_SPEED : constant Speed := 120; use explicit conversions in Ada procedure Increase_Speed (S : Speed); ► D is of type Distance, T is of type procedure Check_Speed (T : Time; D : Distance) is Time, S is of type Speed S : Speed := D / T; Compilation error • Only objects of the same type can begin be mixed together in this fashion if S < SAFETY_SPEED then Increase_Speed (T); Compilation error end if; ► Increase_Speed is expecting a end Check_Speed; Speed parameter not a Time … http://libre.act-europe.fr 89 © ACT Europe under the GNU Free Documentation License
    • Ada is Strongly Typed (2 of 2) 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); … ► Parameter switched procedure Perform_Safety_Checks is T : Time := Get_Time; D : Distance := Get_Distance; begin … Check_Speed (D, T); Compilation error end Perform_Safety_Checks; http://libre.act-europe.fr 90 © ACT Europe under the GNU Free Documentation License
    • The Correct Ada Version 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) is S : Speed := Speed ( Integer(D) / Integer (T)); ► You must convert D and T to begin Integer to perform the division if S < SAFETY_SPEED then ► And then convert the result to Increase_Speed (S); type Speed 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; http://libre.act-europe.fr 91 © ACT Europe under the GNU Free Documentation License
    • But What About? ► How do you know it was type A_Type is …; Safe_Copy (X, Y) procedure Safe_Copy (Source : A_Type; Target : A_Type); and not procedure Try is Safe_Copy (Y, X) X : A_Type := …; Y : A_Type := …; begin ► You don't. That's why Ada Safe_Copy (X, Y); provides name parameters … end Try; http://libre.act-europe.fr 92 © 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 is X : A_Type := …; Y : A_Type := …; begin Safe_Copy (Source => X, Target => Y); … end Try; Named parameter http://libre.act-europe.fr 93 © ACT Europe under the GNU Free Documentation License
    • Avoiding Parameter Confusion in Ada Summary: Two lines of defense ► User defined types ► Named parameters http://libre.act-europe.fr 94 © ACT Europe under the GNU Free Documentation License
    • Example of C/C++/Java Type System Weakness Integer Overflow Semantics © ACT Europe under the GNU Free Documentation License
    • Overflow in C/C++/Java #include <limits.h> void compute () { int k = INT_MAX; k = k + 1; } ► In C/C++ signed integer overflow is undefined, anything can happen • All known implementations quot;wrap aroundquot; ► In Java wrap around semantics are part of the language http://libre.act-europe.fr 96 © ACT Europe under the GNU Free Documentation License
    • Overflow in Ada procedure Compute is K : Integer := Integer'Last; begin Exception raised K := K + 1; at execution time end Compute; ► EVERY time there is an integer overflow in Ada an exception is raised http://libre.act-europe.fr 97 © 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 http://libre.act-europe.fr 98 © ACT Europe under the GNU Free Documentation License
    • The Pernicious Effects of Wrap-Around Semantics: A Java Example final int RADIO_PORT = …; void open (int port) {…} ► The program to the left compiles void send (int port, byte data) {…} fine, and runs … void close (int port) {…} void send_bytes (byte first_byte, byte last_byte) { ► … But there is something wrong open (RADIO_PORT); with it. What ? for (byte b = first_byte; b <= last_byte; b++) { send (RADIO_PORT, b); } close (RADIO_PORT); } http://libre.act-europe.fr 99 © 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++/Java for (x; y; z) {…} Means x; while (y) { …; z; } http://libre.act-europe.fr 100 © ACT Europe under the GNU Free Documentation License
    • The Ada Version is Safe type Port is range 0 .. 255; type Byte is range -128 .. 127; RADIO_PORT : constant Port := …; ► The code on the left runs fine procedure Open (P : Port); procedure Send (P : Port; B : Byte); ► There is a true for loop in Ada procedure Close (P : Port); (unlike C/C++/Java) procedure Send_Bytes (First : Byte; Last : Byte) is begin Open (RADIO_PORT); for B in First .. Last loop Send (RADIO_PORT, B); end loop; Close (RADIO_PORT); end Send_Bytes; http://libre.act-europe.fr 101 © 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 http://libre.act-europe.fr 102 © ACT Europe under the GNU Free Documentation License
    • Side Notes on Ada Types © 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 is type Hash_Index is mod 1023; H : Hash_Index := 1022; begin H := H + 1; -- H is equal to zero here end Try; http://libre.act-europe.fr 104 © 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 is type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun); subtype Working_Day is Day range Mon .. Fri; D : Day := Mon; WD : Working_Day; begin WD := D; -- This is OK WD := Sun; -- This raises an exception end Try; http://libre.act-europe.fr 105 © 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; http://libre.act-europe.fr 106 © ACT Europe under the GNU Free Documentation License
    • Exceptions in Ada © ACT Europe under the GNU Free Documentation License
    • When a Check Fails an Exception is Raised in Ada http://libre.act-europe.fr 108 © 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) http://libre.act-europe.fr 109 © ACT Europe under the GNU Free Documentation License
    • Creating Your Own Exceptions procedure Checks is Internal_Error : Exception; procedure Foo is begin raise Internal_Error; end Foo; procedure Bar is begin Foo; end Bar; begin -- of Checks Bar; end Checks; http://libre.act-europe.fr 110 © ACT Europe under the GNU Free Documentation License
    • What Happens at Execution Time? procedure Checks is Internal_Error : Exception; procedure Foo is begin Exception raise Internal_Error; 3 raised end Foo; 2 procedure Bar is begin Foo; end Bar; 1 begin -- of Checks Bar; end Checks; http://libre.act-europe.fr 111 © ACT Europe under the GNU Free Documentation License
    • http://libre.act-europe.fr 112 © 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 is Internal_Error : Exception; procedure Foo is begin raise Internal_Error; end Foo; procedure Bar is begin Foo; end Bar; begin -- of Checks Bar; exception Exception Handler when E : others => Put_Line (quot;Raised exception : quot; & Exception_Name (E)); Put_Line (Symbolic_Traceback (E)); end Checks; http://libre.act-europe.fr 113 © ACT Europe under the GNU Free Documentation License
    • -bargs: Program binder arguments: -E: give exception traceback -cargs: Compiler arguments: -g: debugging on -gnatl: print out a program listing -gnato: overflow checks on http://libre.act-europe.fr 114 © ACT Europe under the GNU Free Documentation License
    • What Happens at Execution Time with Ada.Exceptions; use Ada.Exceptions; with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic; with Text_IO; use Text_IO; procedure Checks is Internal_Error : Exception; procedure Foo is begin raise Internal_Error; a end Foo; b procedure Bar is begin Foo; c end Bar; d begin -- of Checks Bar; e exception when E : others => Put_Line (quot;Raised exception : quot; & Exception_Name (E)); Put_Line (Symbolic_Traceback (E)); end Checks; http://libre.act-europe.fr 115 © 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; http://libre.act-europe.fr 116 © ACT Europe under the GNU Free Documentation License
    • Catching Your Own Exceptions with Text_IO; use Text_IO; procedure Checks is Internal_Error : Exception; procedure Foo is begin raise Internal_Error; end Foo; procedure Bar is begin Foo; end Bar; begin -- of Checks Bar; exception when Internal_Error => Put_Line (“problem occurred”); when others => Put_Line (“some other exception”); end Checks; http://libre.act-europe.fr 117 © ACT Europe under the GNU Free Documentation License
    • Catching an Exception Where You Want procedure Checks is … begin -- of Checks : : : : to catch some : exception in a region : of code without exiting : : from the subprogram : you can use a declare block : : : : : : end Checks; http://libre.act-europe.fr 118 © ACT Europe under the GNU Free Documentation License
    • Example of a Declare Block procedure Calc (A, B : Float) is C, D : Float; begin … declare Old_C : Float := C; begin C := A * B; D := C ** 2; exception when Constraint_Error => C := Old_C; D := 0.0; end; … end Calc; http://libre.act-europe.fr 119 © ACT Europe under the GNU Free Documentation License
    • Array Pitfalls in C © 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 = quot;bugyquot;; printf (quot;%cnquot;, 0 [str]); printf (quot;%cnquot;, * (str+1)); printf (quot;%cnquot;, * (2+str)); printf (quot;%cnquot;, str [3]); } http://libre.act-europe.fr 121 © ACT Europe under the GNU Free Documentation License
    • C quot;Arraysquot; are Just Pointers: No Safety void display_arr (char *name, char *arr, int n) { #include <stdio.h> int k; #include <string.h> printf (quot;%s = quot;, name); for (k = 0; k < n; k++) char x [4] = {'A', 'B', 'C', 'D'}; printf (quot;%cquot;, arr [k]); char y [4] = {'E', 'F', 'G', 'H'}; printf (quot;nquot;); char z [4] = {'I', 'J', 'K', 'L'}; } … int main () { void display () { char *p; display_arr (quot;xquot;, x, 4); display_arr (quot;yquot;, y, 4); display(); display_arr (quot;zquot;, z, 4); p = x; printf (quot;------------nquot;); memcpy (p, quot;0123456789quot;, 10); } display (); x [6]= '?'; display (); } http://libre.act-europe.fr 122 © 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'}; Set p to the address of x char z [4] = {'I', 'J', 'K', 'L'}; … int main () { char *p; Copy quot;0123456789quot; in the display(); 10 consecutive memory p = x; locations pointed by p memcpy (p, quot;0123456789quot;, 10); display (); Result is undefined since x is a pointer that points to 4 consecutrive x [6]= '?'; preallocated bytes in memory, not 7 display (); compiler is free to do what it wants } http://libre.act-europe.fr 123 © ACT Europe under the GNU Free Documentation License
    • What Happens in Practice http://libre.act-europe.fr 124 © 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'}; A B C D E F G H I J K L char y [4] = {'E', 'F', 'G', 'H'}; char z [4] = {'I', 'J', 'K', 'L'}; x[0] x[1] x[2] x[3] y[1] y[2] y[3] y[4] z[0] z[0] z[2] z[3] … int main () { char *p; display(); p = x; memcpy (p, quot;0123456789quot;, 10); display (); x [6]= '?'; display (); } http://libre.act-europe.fr 125 © ACT Europe under the GNU Free Documentation License
    • Pointer Copy #include <stdio.h> #include <string.h> char x [4] = {'A', 'B', 'C', 'D'}; A B C D E F G H I J K L char y [4] = {'E', 'F', 'G', 'H'}; char z [4] = {'I', 'J', 'K', 'L'}; x[0] x[1] x[2] x[3] y[1] y[2] y[3] y[4] z[0] z[0] z[2] z[3] … int main () { char *p; display(); p = x; p memcpy (p, quot;0123456789quot;, 10); display (); x [6]= '?'; display (); } http://libre.act-europe.fr 126 © ACT Europe under the GNU Free Documentation License
    • memcpy #include <stdio.h> #include <string.h> char x [4] = {'A', 'B', 'C', 'D'}; 0 1 2 3 4 5 6 7 8 9 K L char y [4] = {'E', 'F', 'G', 'H'}; char z [4] = {'I', 'J', 'K', 'L'}; x[0] x[1] x[2] x[3] y[1] y[2] y[3] y[4] z[0] z[0] z[2] z[3] … int main () { char *p; display(); p = x; p memcpy (p, quot;0123456789quot;, 10); 0123456789 display (); x [6]= '?'; display (); } http://libre.act-europe.fr 127 © ACT Europe under the GNU Free Documentation License
    • x[6] = '?' #include <stdio.h> #include <string.h> char x [4] = {'A', 'B', 'C', 'D'}; 0 1 2 3 4 5 ? 7 8 9 K L char y [4] = {'E', 'F', 'G', 'H'}; char z [4] = {'I', 'J', 'K', 'L'}; x[0] x[1] x[2] x[3] y[1] y[2] y[3] y[4] z[0] z[0] z[2] z[3] … int main () { char *p; display(); p = x; p memcpy (p, quot;0123456789quot;, 10); display (); x [6]= '?'; display (); } http://libre.act-europe.fr 128 © 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 http://libre.act-europe.fr 129 © ACT Europe under the GNU Free Documentation License
    • What about C++ and Java ► C++ • Same problem as in C • You can redefine the quot;[ ]quot; operator in C++ thereby providing your own checks and semantics. However this makes code hard to read since when 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 http://libre.act-europe.fr 130 © 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 http://libre.act-europe.fr 131 © ACT Europe under the GNU Free Documentation License
    • One of a Kind Arrays ► In Ada Arrays can have arbitrary bounds procedure Compute (N : Integer) is ► The bounds can be dynamic A : array (1 .. N) of Float; values begin … end Compute; http://libre.act-europe.fr 132 © ACT Europe under the GNU Free Documentation License
    • Typed Arrays procedure Compute (N : Integer) is type Arr is array (Integer range <>) of Float; A : Arr (1 .. N) := (others => 9); ► B takes its bounds from A B : Arr := A; C : Arr (11 .. 20) := (1, 2, others => 0); begin ► If C'Length /= A'Length then C := A; Constraint_Error is raised C (15 .. 18) := A (5 .. 8); end Compute; ► If A'Last < 8 then Constraint_Error is raised http://libre.act-europe.fr 133 © 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 is A : array (1 .. 100) of Integer; begin A (101) := 1; Exception raised end Checks; http://libre.act-europe.fr 134 © 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; A ' First 10 A ' Last 99 A ' Length 90 A ' Range 10 .. 99 http://libre.act-europe.fr 135 © ACT Europe under the GNU Free Documentation License
    • Ada Arrays are Powerful: No Need to Pass Array Bounds as in C/C++/Java procedure Calc is type Vector is array (Natural range <>) of Float; function Max (V : Vector) return Float is M : Float := Float ’ First; begin for K in V ’ Range loop if V (K) > M then M := V (K); end if; end loop; return M; end Max; V1 : Vector := (1.0, 2.0, 3.0); -- V'First = 0 and V'Last = 2 V2 : Vector (1 .. 100) := (1.0, 2.0, others => 5.0); X : Float := Max (V1); -- X = 3.0 Y : Float := Max (V2); -- Y = 5.0 begin … end Calc; http://libre.act-europe.fr 136 © 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 = quot;Hello Hello youquot; http://libre.act-europe.fr 137 © ACT Europe under the GNU Free Documentation License
    • Records and Pointers in Ada © ACT Europe under the GNU Free Documentation License
    • Record Types type Date is record Day : Positive range 1 .. 31; Month : Positive range 1 .. 12; Year : Integer; end record; D : Date := (3, 9, 1975); A : Date := (Day => 31, Month => 12, Year => 1999); B : Date := A; Y : Integer := B . Year; http://libre.act-europe.fr 139 © ACT Europe under the GNU Free Documentation License
    • Pointers and Records 3 9 1975 type Node; type Node_Ptr is access Node; type Node is record D : Date := (1, 1, 1900); 1 Next : Node_Ptr; 1 end record; 1900 P1 : Node_Ptr := new Node; null P2 : Node_Ptr := new Node ’ ((3, 9, 1975), P1); Memory http://libre.act-europe.fr 140 © ACT Europe under the GNU Free Documentation License
    • N : Node := ((31, 12, 1999), null); 31 12 P3 : Node_Ptr := new Node ’ (N); 1999 null Memory http://libre.act-europe.fr 141 © ACT Europe under the GNU Free Documentation License
    • Accessing Record Fields: A Simple Rule If P is a pointer to a record then P.all points to the WHOLE record P.Field points to Field in the record Note: P.Field is the same as P.all.Field type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr; end record; P : Node_Ptr := new Node; A_Date : Date := P.D; A_Node : Node_Ptr := P.Next; http://libre.act-europe.fr 142 © ACT Europe under the GNU Free Documentation License
    • Parametrized Records: Discriminants type Q_Array (Positive range <>) of Integer; type Queue (Max_Size : Positive) is record First : Positive := 1; Last : Positive := 1; Size : Natural := 0; Q : Q_Array (1 .. Max_Size); end record; X : Queue (4); -- X.Max_Size = 4 Compilation Error Y : Queue; Value for Max_Size missing http://libre.act-europe.fr 143 © ACT Europe under the GNU Free Documentation License
    • Parameter Passing in C, Java and Ada © 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 http://libre.act-europe.fr 145 © 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 } http://libre.act-europe.fr 146 © 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 ... void copy (const int x, const int y) { x = y; Warning with GCC } ► In Java void copy (final int x, final int y) { x = y; Compilation error in Java } http://libre.act-europe.fr 147 © 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 void foo (int *p); … • This also makes the code hard to change int s; foo (& s); http://libre.act-europe.fr 148 © ACT Europe under the GNU Free Documentation License
    • Three Parameter Passing Modes in Ada in procedure Open_File (X : String); • It's the default mode, the in can be omitted procedure Open_File (X : in String); • Inside the procedure or function X is a constant function Log (X : Float) return Float; initialized by the value of the actual parameter function Log (X : in Float) return Float; • Functions can only have parameters of mode in in out • Inside the procedure X is a variable initialized by procedure Increment (X : in out Float); the value of the actual parameter • The actual parameter is updated with the last value of X when the procedure terminates. out procedure Copy (Y : Float; X : out Float); • Inside the procedure X is an uninitialized variable • The actual parameter is updated with the last value of X when the procedure terminates http://libre.act-europe.fr 149 © ACT Europe under the GNU Free Documentation License
    • Example: Mode quot;inquot; function Log (X : Float) return Float is begin X := 1.0; Compilation error … X is a constant inside Log end Log; http://libre.act-europe.fr 150 © ACT Europe under the GNU Free Documentation License
    • Example: Mode quot;in outquot; Note: In Ada You can nest functions & procedures procedure A_Test is procedure Increment (X : in out Float) is begin X := X + 1.0; end Increment; Value : Float := 9.0; begin -- Value = 9.0 here Increment (Value); -- Value = 10.0 here end A_Test; http://libre.act-europe.fr 151 © ACT Europe under the GNU Free Documentation License
    • Example: Mode quot;outquot; procedure A_Test is procedure Copy (Y : Float; X : out Float) is begin X := Y; end Copy; Value : Float; begin -- Value is uninitialized here Copy (10.0, Value); -- Value = 10.0 here end A_Test; http://libre.act-europe.fr 152 © ACT Europe under the GNU Free Documentation License
    • C/C++/Java are not good low level programming languages © ACT Europe under the GNU Free Documentation License
    • Representation Clauses http://libre.act-europe.fr 154 © 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 © ACT Europe under the GNU Free Documentation License
    • Language Safety and Security unsafe assembly C++ C Java Ada safe http://libre.act-europe.fr 157 © 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 http://libre.act-europe.fr 158 © ACT Europe under the GNU Free Documentation License