Unit 9 Program Comprehension and Defensive Programming
Unit 9 Program Comprehension and Defensive Programming
Defensive Programming
1
Objectives
• Explain the concept of program comprehension
• Outline the guidelines of good documentation and program style
• Review Types of errors (syntax, logic, run-time)
• Describe the approaches used in Defensive programming (e.g. secure
coding, exception handling)
2
Program Comprehension
3
Program Comprehension
• developers spend most of their time with understanding source code
• program-comprehension models comprise two processes: top-down and
bottom-up processes
4
Program Comprehension
• Goes far beyond the ability to read syntax
• Serious economic issue for the industry
• Program comprehension is required for:
• Defect identification
• Tracing the defect source
• Code inspection
• Preparation of test cases
• Good documentation
• Code revisions and enhancements
5
Top-Down Comprehension Models
• Requires programmers to be familiar with a program’s domain
• a general hypothesis about a program’s purpose is derived
• programmers can compare the current program with other programs they know
• programmers neglect details, but only concentrate on relevant aspects for
building the hypothesis
• Second step is evaluation of the hypothesis
• Programmers look at details and refine the hypothesis step wisely by
developing subsidiary hypotheses
• subsidiary hypotheses are refined further, until the programmers have a low-
level understanding of the source code, such that they can verify, modify, or
reject the hypotheses
• During the refinement process, programmers look sets of features that typically
indicate the occurrence of certain structures or operations in the code
6
Bottom-Up Comprehension Models
• With insufficient domain knowledge
• programmers cannot look for beacons (e.g familiar naming conventions
or programming plans)
• programmers need to examine the code closely to be able to state
hypotheses of a program’s purpose
• programmers start to understand a program by
• examining its details first: the statements or control constructs that comprise the
program
• Statements that semantically belong together are grouped into higher-level
abstractions, referred to as chunks
• If enough chunks are created, programmers leave the statement level and
integrate those chunks to further higher-level abstractions
7
Integrated Comprehension Models
• Simple top-down and bottom-up models often cannot describe the
comprehension process sufficiently
• developers use both processes most of the time which is described as
integrated models
• if programmers have domain knowledge about a program, they form a
hypothesis about its purpose
• If they encounter fragments that they cannot explain with domain knowledge,
they start to examine the program statement by statement and integrate the
newly acquired knowledge into their hypotheses about the source code.
8
Improving program comprehension
• Use of high level languages instead of low level languages
• Reuse already existing code without knowing its implementation (use of
APIs)
• Use of Domain Specific Languages (DSL)
• contain a restricted set of instructions tailored to a certain domain
• reduces the expressive power of a programming language, but makes it easier
to learn and write according programs because instructions are few
• E.g SQL select [column] from [table] where [condition], many common data-
base queries can be expressed
• Using IDEs to manage complex code instead of a text editor
• Code layout (with indentation, different colour codes )
9
Challenges of measuring Comprehension in
modern development
• Too many programming languages with different features
• new programming languages, paradigms, and extensions emerge frequently
• so many tools to support the programmer, and
• for each tool, there are numerous extensions, which often focus on one aspect of
supporting the programmer
• effort to improve the programmer’s life is visible but, sufficient
empirical evaluation is still lacking (Is the effort helping?)
10
Documentation and Program Style
11
Documentation
• Software documentation is written text or illustration that accompanies
computer software or is embedded in the source code
• Why?
• main purpose of program documentation is to describe the design of your
program
• Explains how the software operates or how to use it, and may mean different
things to people in different roles
• Maintenance and debugging (Documentation can help the programmer who is
making the modifications understand your code)
• Documenting your program during development helps you not to loose track of
what you are doing
12
Examples Documentation
• Technical
• Mostly prepared before writing the code
• E.g Pseudocode, Flow charts, Program comments, Test plans,
• User Oriented
• Usually prepared after the program
• E.g user manual
13
Sample Comment Documentation
1. // FILE: enroll.cpp
2. // TITLE: Course Enrollments
3. // SUBMITTED BY: Jelita Mulenga
4. // All code is my own except where credited to others.
5. // FOR COURSE: CS 150
6. // DUE DATE: March 30, 2021
7. //
8. // PURPOSE:
9. // This program will keep track of enrollments in courses at a small
10. // university. It will read, from the user, the course id number and
11. // enrollment for each course offered. The data will then be sorted
12. // from smallest to largest id number. The sorted list will then be
13. // printed along with the total enrollments for all courses.
14
Program style
• A programming style is a set of guidelines used to format
programming instructions
• Following a recommended and familiar style makes it easier for
programmers to understand and maintain code
• Key elements of programming style guide include naming
conventions, use of comments and formatting (indenting, white
spaces)
15
Program Style: Comments
• Comments improve program readability Be consistent with your use of
commenting syntax, for example:
• // This is a line comment
• /* This is a block comment
• over two lines */
• Start each file with a comment at the top describing its contents
• Start each function with a comment describing use of the function
• Variable names should be descriptive enough not to require commenting. If
this is difficult, provide a brief comment at declaration
• Only comment non-obvious, interesting or important parts of your code
throughout implementation
• Follow normal grammatical conventions to ensure readability of comments
16
Program Style: Naming
• When naming variables, functions/methods, classes, files etc. it is important
to follow a naming convention, and use correct English spelling (this assists
with search/find/replace operations)
• Naming conventions are used to improve visual appearance and reduce the
effort needed to read and understand the code. They can vary in different
programing languages. The following items are a good guide:
• All naming should be descriptive where appropriate.
• Avoid abbreviation where possible but seek to keep naming an appropriate mix of
easy to understand purpose but not too long
• Spaces must not be used. Some languages would use an underscore (e.g. total_height
in Python, SQL, C++). Java uses mixed case for variables starting with lowercase e.g.
totalHeight.
• Constants are usually defined as all uppercase using underscores to separate words.
e.g. MAX_HEIGHT, PI
17
Program Style: Indenting and Whitespace
• Indenting and Whitespace requirements for /* comment about this function, parameters and
particular languages supersede any general return typ*/
guidelines (such as Python requirements)
function(parameters) {
• Blank lines should be used to separate logical
groupings of code // code
• Minimum of 2 blank lines should be used to }
separate functions
• Be consistent with choice of tabs or spaces for /* comment about this function, parameters and
indenting. Adjust tab sizing so as not to be return types*/
too large.
function(parameters)
• Aim for best readability. Primary importance
is that code is easy to read and logically {
follow // code
}
18
Defensive Programming
19
Defensive Programming Meaning
• Practices that minimize the likelihood of undefined behaviour arising,
whether currently or during subsequent modification to the code.
• Rationale: Programs should compile without warnings
• if code habitually generates lots of warnings, there is a tendency to miss any
warnings that are genuinely indicative of coding errors.
• Exceptions: Sometimes warnings are issued incorrectly. They are
indicative of errors or inadequacies in the compiler or third-party code
rather than errors in your code.
20
Defensive programming Techniques and Good
practices
• Don’t let any error go undetected (Exceptional handling)
• Minimise the visibility of data (Block Scope / Local Scope for
variables)
• In object oriented make class attributes private
• Restrict access to class attributes
• Make full use of const
• Don’t provide unnecessary default constructors
• Use explicit not implicit type conversions
21
Good practices
• Minimize use of default parameters
• Keep Functions short
• Write for people
• Prefer compile-time to runtime errors
• Say everything exactly once “Don’t Repeat Yourself” (DRY) (Use
functions or subroutines)
22
Exceptions in C++
• Exceptions provide a way to react to exceptional
circumstances (like runtime errors) in programs by transferring
control to special functions called handlers
• ***** Relook at the code for reading from files *******
• Recall on types of Errors
• Syntax (compile time)
• Logical (runtime)
• Semantic (runtime or compile time)
• int a, b, c;
• a + b = c; //semantic error
• Linker (fails to create executable)
• Writing Main() instead of main().
23
C++ try and catch
• Exception handling in C++ consist of try {
three keywords: try, throw and catch: // Block of code to try
throw exception; // Throw an exception when a problem arise
• The try statement allows you to define a }
block of code to be tested for errors catch () {
while it is being executed. // Block of code to handle errors
}
• The throw keyword throws an exception
when a problem is detected, which lets
us create a custom error.
• The catch statement allows you to
define a block of code to be executed,
if an error occurs in the try block.
• The try and catch keywords come in
pairs:
24
Exception Handling: Example 1
• try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough to use Google Services.";
} else {
throw (age);
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Age is: " << myNum;
}
25
Exceptional Handling: Example 2
• try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough to use Google Service";
} else {
throw 505; //you can assign a different value
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Error number: " << myNum;
26
Exceptional Handling: Example 3
• try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough access Google services";
} else {
throw 505;
}
}
catch (...) {
cout << "Access denied - You must be at least 18 years old.\n";
}
27
Exercise
/* Provide Exceptional Handling so that when a user enters a non valid
number, the program should notify the user instead of displaying wrong
information */
#include <iostream>
using namespace std;
int main(){
int a;
cout<<"Enter a value ";
cin>>a;
cout<<"\n The value you entered is"<<a<<endl;
return 0;
}
28
Exercise
• From Lab 4 Exercise
• Add comments and exceptional handling to question 2 and 4
• Exercise (Files)
• Apply exceptional handling instead of the just the if else statement when
opening a file for input in Question 2
29