Download presentation
Presentation is loading. Please wait.
Published bySharon Rodgers Modified over 9 years ago
1
Programming in the Small: C/C++/Java Pitfalls & Ada Benefits Franco Gasperoni gasperoni@adacore.com http://libre.adacore.com/Software_Matters
2
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 2 Copyright Notice © AdaCore 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. A copy of the license is included in available at: http://www.fsf.org/licenses/fdl.html
3
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 3 Suggested Reading C Traps and Pitfalls by Andrew Koenig (Addison Wesley) Guidelines for the Use of the C Language in Vehicle Based Software Purchasing info at http://www.misra.org.uk/misra-c.htm Multilanguage Programming on the JVM: The Ada 95 Benefits http://libre.act-europe.fr/Why_Ada/ada-on-jvm.pdf
4
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 4 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)
5
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 5 Lecture Summary In this lecture we concentrate on programming in the small We go over some Ada basic constructs Procedures, functions, types, loops, if and case statements exceptions, etc. We show some C/C++/Java pitfalls We show how Ada avoids them
6
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 6 What is Programming in the Small ? A computer can only perform very simple operations A program performs complex tasks By grouping together large numbers of simple operations Programming in the large Deals with the overall structure/architecture of the program Programming in the small Deals with the program details once the overall structure is in place
7
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 7 Programming: Abstraction, Structure & Coding Detail Structuring element: Module, package, class, file, … Uses the services of
8
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 8 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
9
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 9 Programming in the Large: Abstraction & Structure
10
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 10 Programming in the Small Programming in the small is also known as coding This activity refers to filling in the details of the program architecture elaborated in the Programming in the Large The details are the explicit, step-by-step instructions for performing fairly small-scale tasks Arithmetic operations, loops, decisions, etc.
11
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 11 Programming in the Small: Coding Detail … max_gnat_nodes = max_gnat_node; number_names = number_name; Nodes_Ptr = nodes_ptr - First_Node_Id; Next_Node_Ptr = next_node_ptr - First_Node_Id; Prev_Node_Ptr = prev_node_ptr - First_Node_Id; Elists_Ptr = elists_ptr - First_Elist_Id; Elmts_Ptr = elmts_ptr - First_Elmt_Id; Strings_Ptr = strings_ptr - First_String_Id; String_Chars_Ptr = string_chars_ptr; List_Headers_Ptr = list_headers_ptr - First_List_Id; … if (Nkind (gnat_root) != N_Compilation_Unit) gigi_abort (301); …
12
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 12 Programming in the Small with C C makes the following assumption: Trust the programmers, they never make mistakes Favor program conciseness over its readability But: Programmers do make mistakes Programs are written once but read many times The C foundation of C++ & Java leads to fragile software Software where it is easy to make mistakes Software that is hard to read Software that is hard to change
13
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 13 Important Note All C/C++/Java code examples showed in this lecture compile Some are correct according to the C/C++/Java semantics Others are specified to be errors in the standards but … … an implementation is not required to detect them They contain coding errors undetected by most C/C++/Java compilers 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 more
14
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 14 Note on the Ada Development Environment In this course we use GNAT GAP Edition GNAT is widely available You can download the sources of GNAT Pre-built GNAT binaries available for: Linux, Solaris, Windows GNAT GPL Edition available at http://libre.adacore.com
15
Background on Ada Programming A Simple Example
16
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 16 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 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; Note: Ada is case insensitive
17
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 17 Inside Procedure Main Declarative part: Contains the declaration of: Variable, types, nested procedures, nested functions,... used in procedure Main with Text_IO; procedure Main 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; Procedure statements
18
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 18 with Text_IO; List of compilation units whose services are used in procedure Main Text_IO is the predefined Ada text Input/Output library with Text_IO; procedure Main 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; Procedures declared in library Text_IO and used in Main
19
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 19 use Text_IO; By putting a use clause you can (but don't have to) omit the Text_IO prefix inside Main with Text_IO; use Text_IO; procedure Main 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;
20
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 20 The ' img Attribute ' img is a predefined GNAT attribute Given an integer or floating point number X, X ' img returns its string representation More on attributes later on with Text_IO; use Text_IO; procedure Main 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;
21
Structure of an Ada Program
22
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 22 General Structure of an Ada Program with …; procedure Some_Main is … begin … end Some_Main; with …; with …; with …; with …; with …;
23
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 23 A Simple Example with Display; with Fact; procedure Display_Fact is begin for K in 1.. 4 loop Display ("Factorial", K, Fact (K)); end loop; end Display_Fact; with Text_IO; use Text_IO; procedure Display (S : String; X, Y : Integer) is begin Put_Line (S & " (" & X'img & ") = " & Y'img); end Display; function Fact (N : Integer) return Integer is begin if N <= 1 then return 1; else return N * Fact (N - 1); end if ; end Fact;
24
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 24 Building & Executing Display_Fact GNAT has an automatic "make" facility: gnatmake Gnatmake Will compile or recompile the Ada sources that need to be compiled It will bind and link them A make file is not necessary
25
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 25 Note on the Concatenation Operator & with Text_IO; use Text_IO; procedure Display (S : String; X, Y : Integer) is begin Put_Line (S & " (" & X'img & ") = " & Y'img); end Display; & = 1 dimensional arrays12345AB12345AB
26
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 26 with Display; with Fact; procedure Display_Fact is begin for K in 1.. 4 loop Display ("Factorial", K, Fact (K)); end loop; end Display_Fact; Note on For Loops In for loops, the loop variable ( K in the example) is implicitly declared The loop variable cannot be modified inside the for loop The loop variable ceases to exist just after the loop
27
Numeric Pitfall in C/C++/Java
28
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 28 #include 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?
29
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 29 Surprised ? Was this the programmer’s intent ?
30
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 30 Numbers in C/C++/Java In C/C++/Java numbers starting with 0 are octal numbers This is a bad choice Error-prone Hard-to-read There is no way to specify numbers in base 2 Very surprising giving the fact that C was meant for to be a low-level systems language Never use octal numbers
31
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 31 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; No surprises in Ada
32
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 32 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 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
33
Lexical & Syntactic Pitfalls in C/C++/Java
34
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 34 #include /* I f *y is zero and x > 0 set *k to the biggest positive integer. * If *y is zero and x <=0 leave *k unchanged. * If *y is not zero set *k to be x divided by *y and increment *y by 1. */ void check_divide ( int *k, int x, int *y) { if (*y = 0) if (x > 0) *k = INT_MAX; else *k = x / *y /* it is safe to divide by *y since it cannot be 0 */; *y++; } Is the Following Code Correct ? This program compiles fine, but has a number of problems. Which ones?
35
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 35 There are 4 Bugs = versus == Using “=“ for assignment and “==“ for equality is a poor choice Use a compiler that warns you when you use “=“ inside tests This is a hard problem because C++ style encourages the use of “=“ inside tests: Dangling else problem Always bracket everything Nested y++ Bad operator precedence *y++ means *(y++) When in doubt use parentheses or separate tokens with white spaces... while (*s1++ = *s2++);
36
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 36 What about Java? = versus == This problem exists in Java for boolean, but has been fixed for other data types Dangling else problem Problem is still there Bad operator precedence *j++ means *(j++) No * operator in Java. This Problem has been solved boolean safety_flag; boolean danger_flag; … if (safety_flag = danger_flag) { sound_alarm (); } This is OK in Java but is often a bug
37
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 37 #include /* I f *y is null and x > 0 set *k to the biggest positive integer. * If *y is null and x <=0 leave *k unchanged. * If *y is non null set *k to be x divided by *y and increment *y by 1. */ void check_divide ( int *k, int x, int *y) { if (*y == 0) { if ( x > 0) *k = INT_MAX; } else { *k = x / *y /* it is safe to divide by *y since it cannot be 0 */; ( *y ) ++; /* or *y ++ */ } The Correct Version
38
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 38 -- If Y = 0 and X > 0 set K to the biggest positive integer. -- If Y = 0 and X <= 0 leave K unchanged. -- If Y /= 0 set K to be X divided by Y and increment Y by 1. procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) 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; Ada Solves all the Previous Pitfalls
39
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 39 -- If Y = 0 and X > 0 set K to the biggest positive integer. -- If Y = 0 and X <= 0 leave K unchanged. -- If Y /= 0 set K to be X divided by Y and increment Y by 1. procedure Check_Divide (K : in out Integer; X : Integer; Y : in out Integer) 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; Simpler Ada Version: "elsif" "and then"
40
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 40 Lexical & Syntactic Clarity in Ada = means equality while := means assignment If you use one instead of the other you get a compiler error No dangling else in Ada If it isn't then you get a compiler error In Ada comments start with -- and go to the end of the line. No other type of comment No ++ operators in Ada No need for a * operator in Ada if … then … -- Must be terminated by an end if; end if ;
41
Operator Precedence & Associativity Pitfalls in C/C++/Java
42
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 42 Operator Precedence & Associativity means It does NOT mean if ((x & mask) == 0) if (x & mask == 0) if (x & (mask == 0) ) means It does NOT mean if ((x < y) && (y < z)) if (x < y < z) if (((x < y) && (1 < z)) || (0 < z)) This is not an exhaustive list. Examples What does hi << 4 + low mean? What does x == y == z mean?
43
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 43 Ada Solution You have to write if x and mask = 0 … if (x and mask) = 0 … You have to write if x < y < z … Gives you a compiler error in Ada if (x < y) and (y < z) …
44
Side Note on Ada Attributes
45
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 45 Attributes Ada types, objects, and other entities can have attributes An attribute is a property of the type, object, etc
46
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 46 Example of Scalar Attributes Given T some scalar type (Integer, Float, etc) Given X an object of type T T ' FirstSmallest value in T T ' LastLargest value in T T ' image (X)String representation of X In GNAT you can use X ' img instead of T ' image (X)
47
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 47 procedure Check_Divide_And_Increment (K : in out Integer; X : Integer; Y : in out Integer) 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 Checked_Divide; Example of Integer ' Last
48
More C/C++/Java Syntactic Pitfalls
49
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 49 // If the signal ahead is clear then increase the speed. void increase _ speed_if_safe ( int speed, int signal) { if (signal == CLEAR); increase_speed (); } Is the Following Code Correct ? This program compiles fine, but has a problem. Which one?
50
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 50 Bugs can Have Serious Consequences
51
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 51 // If the signal ahead is clear then increase the speed. void increase _ speed_if_safe ( int speed, int signal) { if (signal == CLEAR) ; increase_speed (); } Be Careful of Spurious Semicolons
52
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 52 -- If the signal ahead is clear then increase the speed. procedure increase _ speed_if_safe (speed : integer; signal : integer) is begin if signal = CLEAR then increase_speed; end if; end increase _ speed_if_safe; The Ada Version is Always Safe If you write if signal = CLEAR then ; You get a compiler error
53
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 53 More Bad Luck in C/C++/Java: Enumerations and Switch Statements enum Alert_Type {LOW, MEDIUM, HIGH, VERY_HIGH}; // C or C++. Java does not have enumerations, you have to use int s 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?
54
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 54 Defects in the Previous Code void handle_alert ( enum Alert_Type alert) { switch (alert) { case LOW: activate_camera (); break; case MEDIUM: send_guard (); break; case HIGH: sound_alarm (); break; case VERY_HIGH: alert_police (); break; } void process_alerts () { handle_alert (HIGH); Don't forget break statements C/C++/Java do not check that you have treated all cases in the switch case labels can be integers or (values of) any enum type, not just enum Alert_Type which in most cases will be an error
55
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 55 Ada is Safer (and Less Verbose) type Alert_Type is (LOW, MEDIUM, HIGH, VERY_HIGH); procedure Process_Alert (Alert : Alert_Type) is begin case Alert is when 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
56
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 56 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;
57
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 57 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; Ada "when others" is equivalent to C/C++/Java "default", and takes away most of the benefit of the checking for all cases covered
58
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 58 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
59
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 59 Enumeration Types in Ada Enumerations are true types in Ada In C enums are just integers In C++ enums are implicitly converted to ints (not from ints) type Alert is (LOW, MEDIUM, HIGH, VERY_HIGH); procedure P (B : Integer) is A : Alert; begin A := B; Compilation error // C++ enum Alert {LOW, MEDIUM, HIGH, VERY_HIGH}; int k = LOW;// accepted by C++ Alert a = 1; // rejected by C++
60
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 60 Java Does not Have Enumerations :( In Java 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;
61
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 61 Ada Enumeration Types and Attributes Alert_Type ' FirstLOW Alert_Type ' LastVERY_HIGH
62
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 62 Predefined Enumerations in Ada type Boolean is (False, True); type Character is ( …, 'a', 'b', 'c', … );
63
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 63 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;
64
Conciseness Versus Readability
65
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 65 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;
66
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 66 Comment on x = y---z--; Any sensible C/C++/Java programmer would write I still prefer the following more verbose style … it is simpler to understand by the average programmer reading your code This depends on the organization you work in :) x = y-- - z--; x = y - z; y--; z--;
67
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 67 Good Programming is Altruistic Other people read and work on your code Write your code so that others can read and work on it Readability is a function of the programmers in your group Present AND future programmers If you are in a group of gurus it is ok to prefer In most organizations programmers are not gurus In this case is easier to read/work on x = y-- - z--; x = y - z; y--; z--;
68
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 68 Conciseness and Non Determinism What does the following mean: It compiles, but … … Its semantics are undefined It could mean any one of the following (when written in Ada): { int k = 0; int v [10]; k = v [k++]; } declare K : Integer := 0; V : array (0.. 9) of Integer; begin K := V (K); … declare K : Integer := 0; V : array (0.. 9) of Integer; begin K := V (K); K := K + 1; … declare K : Integer := 0; V : array (0.. 9) of Integer; begin Erase_All_Hard_Disks; …
69
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 69 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 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
70
C/C++/Java Type System
71
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 71 What is a Type? A type is characterized by: The set of values an expression of that type can take The operations that can be applied to those values
72
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 72 Pre-Defined and User-Defined Types Some types can be pre-defined by the language E.g. booleans, integers, characters, strings, etc Pre-defined types come with pre-defined operations E.g. for integers: additions, subtractions, etc. Languages typically allow user-defined types and operations User-defined operations are provided in the form of procedures and functions
73
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 73 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
74
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 74 Example int w; w memory 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, remainder, etc. An object with name w The object is a variable
75
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 75 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
76
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 76 Strong Typing is Good It prevents many kinds of crashing bugs It tells the programmer when she has mixed "apples" with "oranges"
77
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 77 Some Examples Strongly (mainly statically) typed languages: Ada, Eiffel, Java Strongly dynamically typed languages Scheme, Smalltalk Weakly typed languages C, C++ Completely untyped languages assembly languages, shell scripts
78
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 78 Typing Problems Common to C/C++/Java typedef in C/C++ is a shorthand it does not define a new type No user-defined types Scalars (characters, integers, reals) Pointers (e.g. there can only be a single pointer to an int type) Arrays (e.g. there can only be a single array of int type) Implicit conversions from integers to reals Weak overflow semantics rules for signed integers Missing types Enumerations in Java (not full types in C/C++) Character types in C/C++ Fixed points Unsigned integers in Java Pointers to functions in Java
79
Example of C/C++/Java Type System Weakness No User-Defined Scalar Types
80
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 80 C/C++ Example The program to the left compiles fine There is something wrong with it What ? typedef int Time; typedef int Distance; typedefint 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); }
81
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 81 Bugs can have Disastrous Consequences
82
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 82 What's Wrong with C/C++ Program compiles fine but has 2 serious flaws that go undetected FLAW 1: t is a Time increase_speed() takes a Speed parameter Time and Speed are conceptually different, they should not be mixed up FLAW 2: Distance and Time parameters have been inverted Time and Distance are conceptually different, they should not be mixed up C/C++ provide NO HELP to the programmer in detecting these mistakes typedef int Time; typedef int Distance; typedefint 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); }
83
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 83 Things are Even Worse in Java There are no typedef in Java Everything must be an int typedef are useful for documentation purposes typedef could be used to perform sanity checks during code walkthroughs or with simple tools This problem is particularly severe in Java given that many API calls have several indistinguishable int parameters: AdjustmentEvent (Adjustable source, int id, int type, int value) final int SAFETY_SPEED = 120; … void check_speed ( int t, int d) { int s = d/t; if (s < SAFETY_SPEED) increase_speed (t); } void increase_speed ( int s) { … } void perform_safety_checks () { int t = get_time (); int d = get_distance (); … check_speed (d, t); }
84
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 84 What About Ada? You can write the same buggy code in Ada, but … … Ada has two lines of defense that do not exist in C/C++ or Java to protect the programmer User defined types Parameter associations -- Buggy code. DON'T write this SAFETY_SPEED : constant Integer := 120; … procedure Increase_Speed (S : Integer); … procedure Check_Speed (T : Integer; D : Integer) is S : Integer := D / T; begin if S < SAFETY_SPEED then Increase_Speed (T); end if; end Check_Speed; procedure Perform_Safety_Checks is T : Integer := Get_Time; D : Integer := Get_Distance; begin … Check_Speed (D, T); end Perform_Safety_Checks;
85
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 85 Defining New Types in Ada Users can define their own types in Ada In C/C++/Java users can only define struct/union/class types No user-defined scalar, pointer or array types -- Example of integer type definition in Ada type Time is range 0.. 3_600; type Distance is range 0.. 1_000; type Speed is range 0.. 4_000;
86
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 86 User Defined Integer Types in Ada Each user defined integer type introduces a new type This new type is NOT a synonym of Integer Each user defined integer type gives its bounds, i.e. the values any object of this type can take Time ' First = 0 Time ' Last = 3_600 type Time is range 0.. 3_600; type Distance is range 0.. 1_000; type Speed is range 0.. 4_000;
87
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 87 Ada is Strongly Typed (1 of 2) When you define the proper types the Ada compiler catches the errors To mix different types you must use explicit conversions in Ada D is of type Distance, T is of type Time, S is of type Speed Only objects of the same type can be mixed together in this fashion Increase_Speed is expecting a Speed parameter not a Time type Time is range 0.. 3_600; type Distance is range 0.. 1_000; type Speed is range 0.. 4_000; SAFETY_SPEED : constant Speed := 120; procedure Increase_Speed (S : Speed); procedure Check_Speed (T : Time; D : Distance) is S : Speed := D / T; begin if S < SAFETY_SPEED then Increase_Speed (T); end if; end Check_Speed; … Compilation error
88
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 88 Ada is Strongly Typed (2 of 2) Parameters switched type Time is range 0.. 3_600; type Distance is range 0.. 1_000; type Speed is range 0.. 4_000; … procedure Check_Speed (T : Time; D : Distance); … procedure Perform_Safety_Checks is T : Time := Get_Time; D : Distance := Get_Distance; begin … Check_Speed (D, T); end Perform_Safety_Checks; Compilation error
89
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 89 The Correct Ada Version You must convert D and T to Integer to perform the division And then convert the result to type Speed type Time is range 0.. 3_600; type Distance is range 0.. 1_000; type Speed is range 0.. 4_000; SAFETY_SPEED : constant Speed := 120; procedure Increase_Speed (S : Speed); procedure Check_Speed (T : Time; D : Distance) is S : Speed := Speed ( Integer(D) / Integer (T)); begin if 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;
90
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 90 But What About? How do you know it was Safe_Copy (X, Y) and not Safe_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 is X : A_Type := …; Y : A_Type := …; begin Safe_Copy (X, Y); … end Try;
91
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 91 Ada has Named Parameters type A_Type is …; procedure Safe_Copy (Source : A_Type; Target : A_Type); procedure Try is X : A_Type := …; Y : A_Type := …; begin Safe_Copy (Source => X, Target => Y); … end Try; Named parameter
92
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 92 Avoiding Parameter Confusion in Ada Summary: Two lines of defense User defined types Named parameters
93
Example of C/C++/Java Type System Weakness Signed Integer Overflow Semantics
94
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 94 Overflow in C/C++/Java In C/C++ signed integer overflow is undefined, anything can happen All known implementations "wrap around" In Java wrap around semantics are part of the language #include void compute () { int k = INT_MAX; k = k + 1; }
95
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 95 Overflow in Ada EVERY time there is an integer overflow in Ada an exception is raised procedure Compute is K : Integer := Integer'Last; begin K := K + 1; end Compute; Exception raised at execution time
96
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 96 Example: Overflow in Action in Ada In GNAT you have to use the switch -gnato to ask for integer overflow checking
97
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 97 The Pernicious Effects of Wrap-Around Semantics: A Java Example The program to the left compiles fine, and runs … … But there is something wrong with it. What ? final int RADIO_PORT = …; void open ( int port) {…} void send ( int port, byte data) {…} void close ( int port) {…} void send_bytes ( byte first_byte, byte last_byte) { open (RADIO_PORT); for ( byte b = first_byte; b <= last_byte; b++) { send (RADIO_PORT, b); } close (RADIO_PORT); }
98
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 98 Infinite Loop when last_byte == 127 Two problems: Wrap around semantics of type byte When last_byte = b = 127 we execute the loop, we do b++ and b wraps to -128 There is no real for loop instruction in C/C++/Java for (x; y; z) {…} Means x; while (y) { …; z; }
99
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 99 The Ada Version is Safe The code on the left runs fine There is a true for loop in Ada (unlike C/C++/Java) type Port is range 0.. 255; type Byte is range -128.. 127; RADIO_PORT : constant Port := …; procedure Open (P : Port); procedure Send (P : Port; B : Byte); procedure Close (P : Port); procedure Send_Bytes (First : Byte; Last : Byte) is begin Open (RADIO_PORT); for B in First.. Last loop Send (RADIO_PORT, B); end loop; Close (RADIO_PORT); end Send_Bytes;
100
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 100 Checks and Overflows Summary In Ada Every integer overflow raises an exception in Ada Every division by zero raises an exception in Ada Every array index overflow raises an exception in Ada Etc. You can disable all the Ada checks for deployment if you wish In Java Java adopted most of the Ada checks except for integer overflow which wraps around in Java Cannot disable checks in Java In C/C++ No checks
101
Side Notes on Ada Types
102
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 102 Unsigned Integers Ada has the choice of two sorts of integer types: Signed integers (an exception is raised in case of an overflow) Unsigned integers (wrap-around semantics) -- Example of unsigned integers in Ada procedure Try is type Hash_Index is mod 1023; H : Hash_Index := 1022; begin H := H + 1; -- H is equal to zero here end Try;
103
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 103 Subtypes Sometimes you want to add additional constraints to a type without creating a new type Ada provides the notion of subtype for that -- Example of unsigned integers in Ada procedure Try 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;
104
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 104 Predefined Ada Subtypes subtype Natural is Integer range 0.. Integer ’ Last; subtype Positive is Natural range 1.. Natural ’ Last;
105
Exceptions in Ada
106
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 106 When a Check Fails an Exception is Raised in Ada
107
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 107 Ada Predefined Exceptions The following predefined exceptions are raised when something goes wrong in an Ada program Constraint_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)
108
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 108 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;
109
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 109 What Happens at Execution Time? 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; 1 2 Exceptionraised 3
110
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 110
111
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 111 Displaying the Traceback (How you Got There) with Ada.Exceptions; use Ada.Exceptions; with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic; with Text_IO; use Text_IO; procedure Checks 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 E : others => Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E)); end Checks; Exception Handler
112
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 112 -cargs: Compiler arguments: -g: debugging on -gnatl: print out a program listing -gnato: overflow checks on -bargs: Program binder arguments: -E: give exception tracebacks
113
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 113 What Happens at Execution Time with Ada.Exceptions; use Ada.Exceptions; with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic; with Text_IO; use Text_IO; procedure Checks 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 E : others => Put_Line ("Raised exception : " & Exception_Name (E)); Put_Line (Symbolic_Traceback (E)); end Checks; a b d c e
114
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 114 Catching a Predefined Exception with Text_IO; use Text_IO; procedure Checks is A : Integer := Integer ’ First; begin A := A - 1; exception when Constraint_Error => Put_Line (“Overflow occurred”); end Checks;
115
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 115 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;
116
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 116 procedure Checks is … begin -- of Checks : end Checks; Catching an Exception Where You Want to catch some exception in a region of code without exiting from the subprogram you can use a declare block
117
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 117 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; Example of a Declare Block
118
Array Pitfalls in C
119
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 119 Arrays in C No real arrays in C An array is just a pointer to a chunk of memory #include 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]); }
120
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 120 C "Arrays" are Just Pointers: No Safety #include 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"); }
121
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 121 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 pointer that points to 4 consecutrive preallocated bytes in memory, not 7 compiler is free to do what it wants Set p to the address of x Copy "0123456789" in the 10 consecutive memory locations pointed by p
122
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 122 What Happens in Practice
123
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 123 What Happens in Memory: Allocation #include 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 (); }ABCDEFGHIJKL x[0]x[1]x[2]x[3]y[1]y[2]y[3]y[4]z[0] z[2]z[3]
124
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 124 Pointer Copy #include 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 (); }ABCDEFGHIJKL x[0]x[1]x[2]x[3]y[1]y[2]y[3]y[4]z[0] z[2]z[3] p
125
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 125 memcpy #include 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; 0123456789 memcpy (p, "0123456789", 10); display (); x [6]= '?'; display (); }0123456789KL x[0]x[1]x[2]x[3]y[1]y[2]y[3]y[4]z[0] z[2]z[3] p
126
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 126 x[6] = '?' #include 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 (); }012345?789KL x[0]x[1]x[2]x[3]y[1]y[2]y[3]y[4]z[0] z[2]z[3] p
127
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 127 C and Arrays: Summary No real arrays Very low level Fundamentally unsafe mechanism Too many ways of expressing the same thing
128
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 128 What about C++ and Java C++ Same problem as in C You can redefine the "[ ]" operator in C++ for class types 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 hard to understand if used in an uncontrolled fashion 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
129
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 129 Arrays in Ada Ada has real arrays (1-dimensional and multi-dimensional) Ada array can have its size determined at run-time Local variable length arrays are allowed in the latest C standard (C99) Ada array bounds can be arbitrary, lower bound does not have to start at 0
130
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 130 One of a Kind Arrays In Ada Arrays can have arbitrary bounds The bounds can be dynamic values procedure Compute (N : Integer) is A : array (1.. N) of Float; begin … end Compute;
131
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 131 procedure Compute (N : Integer) is type Arr is array (Integer range <>) of Float; A : Arr (1.. N) := (others => 9); B : Arr := A; C : Arr (11.. 20) := (1, 2, others => 0); begin C := 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
132
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 132 Arrays in Ada are Safe If you try to index a non-existent arry position, a Constraint_Error exception is raised procedure Checks is A : array (1.. 100) of Integer; begin A (101) := 1; end Checks; Exception raised
133
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 133 Example of 1-Dim Array Attributes Given A some array object A : array (10.. 99) of Integer; A ' First10 A ' Last99 A ' Length90 A ' Range10.. 99
134
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 134 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; Ada Arrays are Powerful: No Need to Pass Array Bounds as in C/C++/Java
135
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 135 Ada String Predefined Array Type type String is array (Positive range <>) of Character; R : String (1.. 10); S : String := (‘H’, ‘e’, ‘l’, ‘l’, ‘o’); T : String := “Hello”; Q : String := S & “ “ & T & “ you”; -- Q = "Hello Hello you"
136
Records and Pointers in Ada
137
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 137 Record Types type Date is record Day : Positive range 1.. 31; Month : Positive range 1.. 12; Year : Integer; end record ; D : Date := (3, 9, 1975); A : Date := (Day => 31, Month => 12, Year => 1999); B : Date := A; Y : Integer := B. Year;
138
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 138 type Node; type Node_Ptr is access Node; type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr; end record ; P1 : Node_Ptr := new Node; P2 : Node_Ptr := new Node ’ ((3, 9, 1975), P1); Memory 1 1 1900 null 3 9 1975 Pointers and Records
139
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 139 N : Node := ((31, 12, 1999), null ); P3 : Node_Ptr := new Node ’ (N); Memory 31 12 1999 null
140
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 140 Accessing Record Fields: A Simple Rule If P is a pointer to a record then P.all points to the WHOLE record P.Field points to Field in the record Note: P.Field is the same as P.all.Field type Node is record D : Date := (1, 1, 1900); Next : Node_Ptr; end record ; P : Node_Ptr := new Node; A_Date : Date := P.D; A_Node : Node_Ptr := P.Next;
141
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 141 Parametrized Records: Discriminants type Q_Array (Positive range <>) of Integer; type Queue (Max_Size : Positive) is record First : Positive := 1; Last : Positive := 1; Size : Natural := 0; Q : Q_Array (1.. Max_Size); end record; X : Queue (4); -- X.Max_Size = 4 Y : Queue; Compilation Error Value for Max_Size missing
142
Parameter Passing in C, Java and Ada
143
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 143 Two Parameter Passing Modes in C/Java By value By constant value In C++ there are additional modes By reference By constant reference
144
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 144 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 }
145
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 145 By Constant Value In C In Java void copy ( const int x, const int y) { x = y; } Compilation error void copy ( final int x, final int y) { x = y; } Compilation error
146
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 146 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);
147
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 147 Three Parameter Passing Modes in Ada procedure Open_File (X : String); procedure Open_File (X : in String); in It's the default mode, the in can be omitted Inside the procedure or function X is a constant initialized by the value of the actual parameter Functions can only have parameters of mode i function Log (X : Float) return Float; function Log (X : in Float) return Float; procedure Increment (X : in out Float); in out Inside the procedure X is a variable initialized by the value of the actual parameter The actual parameter is updated with the last value of X when the procedure terminates. procedure Copy (Y : Float; X : out Float); out Inside the procedure X is an uninitialized variable The actual parameter is updated with the last value of X when the procedure terminates
148
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 148 Example: Mode "in" function Log (X : Float) return Float is begin X := 1.0; … end Log; Compilation error X is a constant inside Log
149
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 149 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; Example: Mode "in out" Note: In Ada You can nest functions & procedures
150
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 150 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; Example: Mode "out"
151
Ada Offers a Comprehensive Scheme for Safe Low-Level Programming
152
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 152 PSW Example Represent the following program status word (PSW): PSW is 24 bits Bits 0 to 7 contain a 7 bit system mask Bits 12 to 15 contain a 4 digit protection key Bits 20 to 24 contain the status flags of the machine for the program The fours flags are called: A, M, W and P All other bits are unused System Maskunused Protection Key unused Machine State 07811121516192023
153
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 153 The PSW Type in Ada type State is (A, M, W, P); type Byte_Mask is array (0.. 7) of Boolean; type State_Mask is array (State) of Boolean; type Program_Status_Word is record System_Mask : Byte_Mask; Protection_Key : Integer range 0.. 15; Machine_State : State_Mask; end record; for Program_Status_Word use record System_Mask at 0 range 0.. 7; Protection_Key at 0 range 12.. 15; Machine_State at 0 range 20.. 23; end record; for Program_Status_Word ' Size use 3 * System.Storage_Unit; System Maskunused Protection Key unused Machine State 07811121516192023
154
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 154 Accessing PSW Fields in Ada is … Simple Safe Efficient PSW : Program_Status_Word := …; Key: Integer := PSW. Protection_Key; M_State : Boolean := PSW. Machine_State (M); Mask_3: Boolean:= PSW. System_Mask (3); … type Program_Status_Word is record System_Mask : Byte_Mask; Protection_Key : Integer range 0.. 15; Machine_State : State_Mask; end record; …
155
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 155 There is more in Ada to help with safe and efficient low-level programming than just the previous example
156
Interfacing Ada with C Is Part of the Ada Standard
157
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 157 "Ada Can Call C" You can call C routines from Ada code -- Ada … procedure Make_Dir (Dir_Name : String) is C_Dir_Name : String := Dir_Name & ASCII.NUL; function mkdir (Dir_Name : String) return Integer; pragma Import (C, mkdir, "__gnat_mkdir"); begin if mkdir (C_Dir_Name) /= 0 then raise Directory_Error; end if ; end Make_Dir; … /* C */ int mkdir ( const char *s) { … }
158
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 158 "C Can Call Ada" You can call Ada routines from C code -- Ada … procedure My_Example (X, Y : Integer); pragma Export (C, My_Example, "_ada_example"); … /* C */ extern void _ada_example ( const int x, y); void try_it () { _ada_example (3, 4); }
159
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 159 There is more to interfacing than these simple examples
160
Summary: Better Safe than Sorry
161
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 161 Language Safety and Security C++CJavaAdaunsafesafeassembly
162
http://libre.adacore.com © AdaCore under the GNU Free Documentation License 162 Summary A good programming language Encourages the writing of correct software Helps in detecting errors C/C++/Java Encourage the writing of concise code not correct software C/C++ provide no help in detecting errors Java provides some help Ada (and other languages such as Eiffel) Encourage the writing of correct software Provide help in detecting errors
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.