By Xulong Pengcampus.murraystate.edu/academic/faculty/wlyle/415/2014/Peng.pdf · In C++, the basic...
Transcript of By Xulong Pengcampus.murraystate.edu/academic/faculty/wlyle/415/2014/Peng.pdf · In C++, the basic...
Programming Language C++
By Xulong Peng
CSC415 Programming Languages
For Dr. William Lyle
October 28, 2014
Page | 1
1. History of C++
Before we describe C++ programming language, we have to introduce C language as C++ was
developed directly from C language. C language was initially developed by Dennis Ritchie at AT & T Bell
Laboratories in the late 1960s and early 1970s (Prata, 2012). At the beginning, it was developed to
support UNIX operating system. Traditionally this kind of operation can be implemented by using
assembly language, a low-level language, which can directly work with hardware efficiently. However,
this low level language is machine dependent which means it works specifically on a particular type of
computer. Because UNIX needs to work on various computer platforms, Ritchie wanted to write a high-
level language which would gear toward problem solving instead of specific hardware. Later this high-
level language can be translated into the internal language of a particular computer using a special
program, called a compiler. C language was developed with this background. Thus, C language is a high
level language, but it combines low level efficiency, Central Processing Unit (CPU) and memory access
(machine dependent) with high level generality and portability (machine independent). C language is a
very efficient procedure language which emphasizes algorithms and it has facilities for structure
programming and also produces compact, fast-running programs with the ability to access internal
hardware parts such as CPU registers, memory location and disk drives.
C++ is a general purpose programming language. It evolved from C language. It combines
imperative, generic and Object-Oriented Programming (OOP) features while keeping C language’s ability
of low level memory manipulation and efficient flexible features (Sebesta, 2013). C++ was also
developed by Bell Labs and was written by Bjarne Stroustrup in 1979 under the name “C and Classes”
and later was renamed to C++ in 1984 (Stroustrup, 2013). The first commercial version of C++ was
released in 1985 and was standardized by the International Organization for Standardization (ISO) in
1998 (Stroustrup, 2013). So far three standardized C++ were released which are the 1998 Standard, the
Page | 2
2003 Standard and the 2011 Standard. The 2014 Standard will be released soon1. C++ added a new
approach, OOP and it fits the language to the problem. Unlike C language, which emphasizes algorithm,
C++ emphasizes data and it designs data forms which focus on essential features of a problem (Prata,
2012). Compared to C language, C++ has many new features, such as classes (data abstraction) which
are OOP features, operator overloading, templates, exception handling, stricter type checking and more
versatile access to data and functions. These features are introduced in the following sections.
2. Design, Syntax and Semantics in C++
2.1 Names, Bindings and Scopes
A name, also called an identifier in C++, follows the same rules as the language C. C++ imposes
no limit on how many characters can be used to identify an entity. But it is actually limited by some
parts of an implementation, such as a linker, and some run-time environment also limits the length of
accepted characters in an identifier. Except the length of identifiers, it does have rules as most
programming languages: Name consists of a letter followed by a string consisting of letters, digits and
underscore (_) used to identify some entity in a program (Stroustrup, 2013). Names in C++ are case-
sensitive (that is Car and car are different names). In addition, C++ has some keywords such as new or
int cannot be used for the naming of an entity.
A binding is to make an association between an attribute and an entity, such as variable and its
type or value for some scope of time and place (Sebesta, 2008). A variable must be bound to a data type
before it is referenced. Binding can be static or dynamic. Static binding refers to compile time binding
therefore it is also called “early binding” and dynamic binding refers to running binding therefore it is
also called “late binding”. C++ is an OOP and it truly implements dynamic binding. Dynamic binding is a
way to implement polymorphism which is one of fundamental components in OOP.
1 https://isocpp.org/std/status
Page | 3
A variable scope is a specific part of the program text in which the variable is visible. C++
includes a few different ranges of scope which are local scope, class scope, namespace scope and global
scope.
a. Local scope: a variable is declared in a program unit or block.
b. Class scope: a class member name is defined in a class but outside of any function.
c. Namespace scope: it extends from the point of declaration to the end of its namespace.
d. Global scope: a variable definition appears outside the functions and it can be hidden by a
local variable with the same name but can be accessed using the scope operator (::).
2.2 Data Type
A data type is a collection of data values and associated operation for manipulating those data
(Sebesta, 2008). The fundamental data types in C++ include numeric types which are number (integer,
floating and double-point), Boolean, character, void (used to signify the absence of information), pointer,
array, reference type. C++ also supports user defined data types, such as enumerated data type.
Integer is the most common numeric data type. C++ has signed and unsigned integer which
include char, short int, int, long int and long long int. The size of an int variable is at least 32-bits and
long int can be at least 64-bits wide. Floating-point types include float, double and long double. In
floating-point types, precision and range are used to represent the collection of values. Precision defines
how accurate the fractional part would be and range is the total length (range of fraction and range of
exponents).
Boolean can have one of two values, true or false. Numeric expressions can be used for Boolean
type (for example ‘0’ represents false and otherwise true) in C++ which sounds very odd. Although it is
more flexible it reduces readability. Therefore use Boolean type when it is needed, such as in switches
or flags, is a good practice as it is more readable.
Page | 4
C++ provides a variety of character types. They are char, signed char, unsigned char, wchar_t,
char16_t and char32_t. The latter two are used for 16-bit and 32-bit character sets, such as UTF-16 and
UTF-32. A single character enclosed in single quotes is called a character literal which is also a char type.
In C++, character literal can be implicitly converted into an integer. Using character literals can make a
program more portable. C++ uses char arrays to store character strings handled by its standard library
functions (Deitel, Paul and Deitel, Harvey, 2012), such as strcopy, strcat and strcmp. Because it is unsafe
and may cause errors, the string class from standard library should be used instead of char arrays in C++.
There are two places use void type in C++. When a function does not return a value or it can be
used as a base type for pointers to unknown type objects.
Pointer is a very powerful data type in C++. It can be used for indirect address of memory and it
is also used for managing dynamic storage (Sebesta, 2008). In C++, a pointer stores the memory address
of any other entity. Pointer operators include reference and dereference. C++ provides pointer for the
management of a heap. It uses new operator for allocation of heap objects and uses delete as its
deallocation operator. The reference data type is similar to pointer. The difference is that reference
refers to an object in memory but pointer refers to an address in memory.
In C++, an array is a consecutive group of memory locations that have the same type. By default,
C++ indexes the first element of an array as 0 (zero). A jagged array is an array whose elements are
arrays. The elements of a jagged array can be of different dimensions and sizes. C++ supports jagged
array and uses row major order which means the rightmost dimension changes fastest.
C++ also supports structures (called struct) data type which is a user-defined data type. It is
composed of fields or members that can have different types. In C++, this data type is the same as class
type except its members are public access. It is used as an encapsulation structure which will be
introduced in section 2.7. Enumeration type in C++ is another user-defined data type and it consists of a
set of named integral constants. C++ can assign enumeration constants to a numeric type but they must
Page | 5
be cast to the type of the assigned variable. As an OOP language, C++ has its OOP feature’s data type
called class. A class is defined to have a set of members and member functions. A class is used to create
objects. An object is an instantiation of a class. A class is the type and an object of the class is the
variable. Section 2.7 will discuss class type in details.
In terms of type conversions, it includes narrowing conversion (such as double to float) and
widening conversion (such as int to float). Widening conversion is safer than narrowing conversion but it
can reduce accuracy. Data type can be either implicitly converted or explicitly converted. Explicit
conversion in C++ is called cast and it uses parentheses to specify the desired type.
2.3 Expression and Assignment Statements
An expression represents a single data item. It is any combination of symbols that represents a
value and it consists of at least one operand and can have one or more operators. C++ provides a rich
set of operators and most of them can be overridden by programmers. However, user can not define a
new operator. C++ has unary (postfix ++, -- and prefix ++, -- and unary +, -), binary (which has two
operands) and ternary operators (? :). Arithmetic operators in C++ do the same as operators in most
languages do. But C++ provides the modulus operator (%) which yields the remainder after integer
division and it can only be used in integer operands (Deitel, Paul and Deitel Harvey, 2012). C++ also
supports equality, equal (=) and not equal (≠) , and relational operators which include greater than (>),
less than (<), greater than or equal (≥), less than or equals(≤). The order of evaluation of expression is
based on operator precedence. The flow of statements in C++ is based on operator associativity and
precedence. The most frequently used operators in descending order of precedence are: scope
resolution ::, (), postfix ++/--, prefix ++/-- and unary +/-, ! and ~, * or / or %, << and >>, relational
operators (<, <=, >, >=), == and !=, bitwise (&, ^, |), logical (&& and ||), ternary conditional (?:), and
Page | 6
assignment (+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=). The associativity can be left-to-right or right-to-left
depends on particular operators (Stroustrup, 2013).
C++ has three different classes of statements: expression, compound and control statements. A
single expression statement consists of an expression using the equal (=) sign for the assignment
followed by a semicolon. For example, a = 10;. A compound statement, also called a group statement,
consists of one or more individual statements using a pair of braces { } to enclose them. A control
statement is used to control when to execute the particular pieces of the program. In C++, the basic
control statements are if/else, loop and switch. The control statement structure will be discussed in
details in the next section.
2.4 Statement-Level Control Structure
C++ has three kinds of control structures which are sequence statements, selection and iterative
statements. To implement a C++ program, a single or combination of these statements is used. Selection
statements offer a choice between two or more executions. Selection statements types are if, if/else
and switch. Two-way selection statements are if-else statements start with the reserved word if
followed by a conditional statement. The control expression in C++ can use either arithmetic or Boolean
expression which is different from most languages that only use Boolean expression. If can be used
individually or used in if-else combination depending on application need. If there are more than one
statement which needs to be executed, then a pair of brackets { } must be used otherwise unexpected
results could happen. Below is an example of if-else statement:
If (condition expression)
{
Statements (if condition expression is true)
}
else
Page | 7
{
Statements (if condition expression is false)
}
As mentioned in section 2.3, C++ only has a ternary operator (?:) which is actually a conditional
operator and it is closely related to the if/else statement.
Nested if/else statements test for multiple cases by using if/else statements inside other if/else
statements. It could cause problems because if/else can mismatch. C++ provides another control
structure, switch, which selects among a set of alternatives (case-labels) and a default case to perform
many different actions. Each action is associated with a case label. The case label must be a constant
expression of integer or enumeration type (Stroustrup, 2013). A general switch statement form is shown
below (Sebesta, 2008):
Switch (expression)
{
case constant expression1:
Statement;
…
case constant expressionn:
Statementn;
[default: Statementn+1;]
}
In switch statements, default is optional which executes when no match occurs between the
controlling expression’s value and a case label. Switch statements are very useful if there are multiple-
selection statements to be handled. C++ switch statements have no restrictions on the placement of the
case expression; and if there is no break at the end of selected segment, execution continues into next
Page | 8
segment. Also, if default is not provided, an unexpected result could occur. Switch is very easy to
compile and implement efficiently but need to be very careful in written because of above problems.
An Iterative statement, also called repetition statement or loop statement, means a program
needs to repeat an action while some condition remains true. This kind of statement in C++ includes for,
while and do…while statement. A for loop specifies the control-controlled repetition details in a single
line code. The for loop syntax is:
for (counter initialization; condition; counter update)
{
Statement(s) to execute while the condition is true;
}
Counter initialization is evaluated only once. Condition is the loop control and is evaluated
before each execution of loop body. In C++, as it was discussed before, condition expression can be
either arithmetic or Boolean and a zero value means false and all nonzero value means true. Therefore if
condition expression is zero, the for loop is terminated; otherwise loop body is executed. In addition, all
expressions of for are optional and if condition is absent then loop will be executed infinitely as the
condition is implicitly considered true (Deitel, Paul and Deitel Harvey, 2012). The body can be a single or
a compound statement; a null statement is also legal. Therefore, C++’s for loop is very flexible.
C++’s while loop is similar as for loop but it strips initialization and update expression of for loop.
It has only condition expression. However, unlike for loop, an empty condition in while is illegal. The
while loop syntax is:
while (condition expression)
{
Statement(s) to execute while the condition is true;
}
Page | 9
If the statement must be executed once for some condition, then it is better to use do…while
loop. The difference between do…while and while is that statement(s) must be executed once in
do…while loop but while does not. The syntax of do... while is:
do
{
Statement(s) to execute
} while (condition);
Notice from here that the condition is evaluated after the loop body and if the condition
remains true, it jumps back to the beginning of the statement to execute.
C++11 also provides a range-based for loop. It simplifies one common loop task and iterates
each element over a container class, array or vector. The syntax is as:
attr(optional) for (range_declaration: range_expression)
{
loop statement.
}
C++ provides statements break, continue, goto and return to alter the flow of control. The break
statement causes immediate exit from the statement and it is used to leave the loop body “in the
middle”. The continue statement is used to skip the rest of the body of the loop but continue to execute
with the next iteration of the loop. The goto statement is used to jump to a location labelled by the
specified identifier (Stroustrup, 2013). The return statement is used to terminate execution of the
program and returns specified value to the caller. If return type is void then it just terminates the
current program and returns to the caller.
2.5 Subprogram
Subprogram, also called procedure or function, executes a specific task through sequence
instructions which generally packaged as a unit. Every subprogram has a single entry point. When it
Page | 10
executes, the calling programing unit is paused until subprogram execution terminates and then control
flow returns to the caller (Sebesta, 2008). C++ uses prototype as a function declaration and it usually
saved in header files. In the prototype, parameters (also called formal parameters) type is checked when
function executes. In C++, default value for formal parameters is acceptable and must appear last. The
general form of a subprogram is list below:
typeName subprogramName (parameterList)
{
Statements;
Return value;
}
If typeName is void, then no return value is needed. The number of parameters ranges from
none to many. Subprogram is called using subprogram name and a list of actual parameters to be bound
to the formal parameters. In the subprogram, local variables can be declared within the subprogram and
these variables are stack dynamic unless declared as static.
C++ parameters can be passed by value, reference or const-reference. If a parameter is passed
by value, a copy of the parameter is made. Then the value can be used as a local variable in the
subprogram and changes made to the formal parameter by the called function have no effect on the
matched actual parameter. If a parameter is passed by reference, then the actual parameter is passed
which means changes made to the formal parameters affect the actual parameter. C++ uses a pointer as
a parameter to implement passing by reference method. In C++, a subprogram name can be sent as a
parameter by using a pointer to the function because function pointer is a type which points to a
function. It can be called by dereference the function pointer. If a parameter is passed by const-
reference, it will not make a copy of parameter but it also cannot change the actual parameter as it is a
constant reference (Deitel and Deitel, 2012; Prata 2012).
Page | 11
In order to speed up the programs, an inline function can be used in C++. The inline specifier is a
hint to the compiler so that it is going to generate code for a call of the function (Stroustrup, 2013). With
inline code, the function performs a little faster than other functions because it does not need to jump
around to execute the code and then jump back (Prata, 2012).
Function overloading enables to define several functions with the same name as long as they
have different signatures (Deitel and Deitel, 2012). It means that programmers can attach more than
one function to the same name, thus overloading the name. The key is signature which is a combination
of a function’s name and its parameter types (in order). The signature in function overloading differs
either in the number of arguments or in the type of arguments or both (Prata, 2012). Overloaded
functions implement similar operations which involve different program logic on different types. When
these logic and operators are identical for each data type, they can be performed more generically,
which are called function templates.
In C++, a function template defines a function begin with the keyword template (lower case) in
terms of a generic type for which a specific type can be substituted. The general form of function
template is descripted as below:
template <template parameters>
// template parameters have the form of either class or typeName identifier.
When the function is called, the function passes a type as a parameter to a template and C++
automatically generates a function for that particular type (Deitel and Deitel, 2012). Below is the
example for a swapping temple:
template <typeName T>
void swap (T &x, T &y)
{
T temp;
temp = x;
Page | 12
x = y;
y = temp;
}
C++ function template is useful, as it only defines a single function but essentially, it defines a
whole family of overloaded functions. When it is in the call, the formal parameters in the template are
dynamically bound to the types of actual parameters.
2.6 Abstract Data Type and Encapsulation Constructs
Abstraction allows one to collect instances of entities into groups which only include the most
significant attributes. Abstract data type (ADT) is a model of a certain kind of data structure that
describes the concepts of their functionality without describing the implementation (Sebesta, 2008).
Process abstraction and data abstraction are two kinds of abstractions. Subprograms are process
abstractions as they provide a way for a program to specify that some process is to be done without
providing the details of how it is to be done. In object-oriented programing language (OOP), a special
ADT is called an object. Encapsulation and information hiding are the most important characteristics in
ADT and data abstraction is one of OOP’s fundamental components.
Encapsulation is a grouping of subprograms and the data that they manipulate. Encapsulation
provides an abstracted system and a logical organization for the collection. An ADT is simply an
encapsulation and it includes only the data representation of the data type and the subprogram that
provides the operation for that type.
As an OOP language, C++ supports two kinds of ADT, all build-in data type and user-defined
abstract data type. Two similar user-defined constructs in C++, class and struct, both directly support
abstract data types. A class includes both data and functions but struct is commonly used when only
data are included. Therefore only class is discussed here to represent user-defined ADT.
Page | 13
In C++, a class is a type. The data and functions defined in a class are called data members and
member functions respectively. Because class members are associated with the class, only instance
members are discussed here. In order to provide ADTs, an instance of a class must be declared and then
a C++ program unit can access any of the public entities in a class through an instance of the class
(Sebesta, 2008). A class instance can be static, stack dynamic or heap dynamic. A class instance is
referenced through a pointer when it is heap dynamic. It must be create explicitly with new operator
and destroyed with delete operator.
A C++ class can contains both hidden and visible entities. To hide entities in a class, the entities
are placed in a private clause, as opposite, entities of a class are visible if they are placed in public clause.
C++ allows to include both constructor and destructor functions and they both can be either
implicitly or explicitly called. If a constructor is called, it initializes the data member of newly created
instance (or object) and then the instance is prepared to be used. If there is a pointer member in the
instance, the constructor also allocates the memory in the heap for the object. A Constructor can be
overloaded if there are multiply constructors in the class definition but they should have different
signatures to differentiate them. When destructor is called, the object ends its lifetime and disassembles
itself. As mentioned above, it must use delete operator on the pointer member to deallocate the
memory back to system if the instance has such pointer member which references heap-dynamic data
otherwise a memory leaking could happen.
C++ also supports parameterized ADTs such as a stack ADT which can store any scalar type
elements. In C++, such element type can be made generic through a template class and template was
introduced earlier in Section 2.6 in details.
2.7 Support for Object-Oriented Programming
Unlike traditional logical procedure language which takes input data and then processes it to
produce output results, Object-oriented programming (OOP) is a model organized around objects and
Page | 14
data as well as associated methods rather than action and logic. OOP languages are now very popular
languages. As an OOP language, it must have three language components: abstract data type (ADT),
inheritance and polymorphism (or dynamic binding). These three capabilities can improve the design,
structure and reusability of programs. ADT was discussed in the last section. In this section, we focus on
the remaining two fundamental components, inheritance and polymorphism.
Since 1980s, one software development trend is software reuse as it increases productivity for
software developers (Sebesta, 2008). OOP language makes software reuse possible as inheritance offers
a solution for modifying abstract data type reuse and program organization. Inheritance means an ADT
can inherit the data and methods of existing type and also can modify some of existing entities and add
new entities. Inheritance can put related classes in hierarchical orders and further to show the
relationships of those related classes. By defining a class that is based on another class using inheritance,
such class is called a derived class. The class it is derived from is called a base class or parent. Derived
class can have new data members and member functions but it also can override the inherited method
because the derived class inherits the base class’s members and methods. If a class has multiple parent
class, then it is called multiple inheritances.
Polymorphism means some program or operations or objects behave differently in different
contexts. Polymorphism allows software system to be more easily extended during both development
and maintenance (Sebesta, 2008).
C++ is the one of the dominant OOP languages and it is still widely used today. C++ was
developed from C with classes added to it (remember its original name “C with classes”). Therefore, C++
includes both low-level features, such as direct memory access and high-level features, such as objects
and it supports both procedure and OOP. In the term of inheritance, C++ can be stand-alone or has a
superclass. In a C++ class, it must have one or more constructors as objects in C++ must be initialized
first before they can be used. Unlike other OOP languages, such as java, C++ provides multiple
Page | 15
inheritances which mean a derived class can inherit from more than one base class. Such multiple
inheritance has some disadvantages: compare to single inheritance, it is more difficult to implement and
maintain. It is also more restrictive and therefore using multiply inheritance should be very careful.
From inheritance, we learned that the relationship between a derived class and its base class is
an “is a” relationship because a derived class basically “is a” base class. The “is a” relationship clearly
demonstrates that an object of a derived class can be treated as an object of its base class. Therefore,
C++ allows to create a pointer variable, such as an array of base class pointers, to point objects of any
publicly derived class types, making it a polymorphic variable (Deitel and Deitel, 2012). When such
polymorphic variable is used to call a member function overridden on one of the derived classes, the call
must be dynamically bound to the correct member function definition (Sebesta, 2008). To do that, a
reserved word virtual must be used to declare a member function to be dynamically bound. If a virtual
function is set to 0, then it is a pure virtual function which means it cannot be called. In C++, the class
which includes a pure virtual function is called an abstract class and it cannot be instantiated. To call a
pure virtual function, this function must be redefined in derived class to implement it.
2.8 Exception Handing
Exception in computer languages is an execution error that a program may indicate, such as
division by zero, access to an array outside of its bounds etc. An exception is an unusual event and may
require a special processing called exception handling. It allows a program to continue execution, or
notify the users of the program or/and terminate the program in a controlled manner. Exception
handling is very important in computer languages as it allows developers to separate normal processing
from error processing and therefore improves the program’s structure, organization and reusability
which make programs robust and fault-tolerant. Exception handler is the exception handling code unit.
Page | 16
C++ uses try clause and a list of exception handler functions - catch functions - to deal with
exceptions. The general expression of try…catch is (Sebesta, 2008):
try{ //code that might raise an exception}
catch (formal parameter){ //a handler body}
…
catch (formal parameter){ //a handler body}
…
//code to execute if no exception or catch handler handled exception
In C++, an exception is a class that is either user or library defined and must be explicitly raised
using statement throw whose general form in EBNF is throw [expression]. Code that might raise an
exception is in the try block and must explicitly use throw expression which selects a particular catch
handler in which its formal parameter matches. throw without expression could appear in catch block.
In that case it re-raise the exception. When an exception occurs in the try block, the try block expires
and program will search the catch functions in sequential order until first match handler is found and
code within the matching catch handler executes. Because handlers are sequentially searched, the
handlers for the specific exceptions are first followed by generic handler (Sebesta, 2008). C++ exception
is very useful. However, it is poorly used, it can create more problems than it solves by creating a false
sense of security.
2.9 Concurrency
Concurrency allows the execution of multiple tasks simultaneously. It is widely used to improve
throughput or to improve responsiveness (Stroustrup, 2013). Concurrency is able to create another
thread of control, to establish timing relationships among threads (synchronization) and to correctly
transmit data among threads (thread communications). A thread is the system-level representation of a
computer’s facilities for executing a task. Original C++ standard only supports single thread
Page | 17
programming. C++ revised standard 2011 adds concurrency to the language for the first time in the form
of the C++11 model. C++ introduced a new thread library including utilities for starting and managing
threads. The standard library directly supports concurrent execution of multiple threads in a single
address space (Stroustrup, 2013). The support includes:
1. A memory model;
2. Programming without locks;
3. A thread library including thread, condition_variable and mutex;
4. A task support library: future, promise, package_task and async.
Mutex is used to protect shared data. It enables to mark the codes that access the data
structure as mutually exclusive so that if any thread is progressing then other threads has to wait.
Condition_variable and future are used to support synchronization. Since concurrency was introduced
into C++ standard 2011. Adding concurrency to C++ standard 2011 enables C++ adaptive to the current
programming style.
3. Evaluation of C++
3.1 Readability
There are a number of criteria to evaluate readability which includes overall simplicity,
orthogonality, data types and syntax design. Each of these is discussed below.
C++ is not an overall simple language which complicates its readability. It has so many features
for developers to learn and many programmers might just learn only a subset. In C++, a particular
operation could be implemented in many ways. For instance, the following four operations can do the
increment and all is valid: (1) x = x + 1; (2) x += 1; (3) x++; (4) ++x;. In addition, C++ supports user
defined operator overloading which could cause confusion as a single operator symbol may have more
than one meaning. Although overloading can aid readability, it can be harmful to readability as well. For
example, ampersand (&) in unary (&a) and binary operator (a & b) has totally different meanings in C++.
Page | 18
Orthogonality means that a relative small set of primitive constructs can be combined in a
relatively small number of ways to build the control and data structures of the languages (Sebesta,
2008). In general, orthogonality means being independent, not related, non-redundant and not
overlapped. The lack of orthogonality affects C++’s readability and writability. For example, in the
expression a + b, b is affected by the type of a as if a is a pointer which could be pointed to any data
type of variable or data structure.
C++ supports numeric types as Boolean expression. Though it is flexible, it definitely affects its
readability as such expression like flag = 1 is ambiguous and difficult to read. If it uses Boolean type then
flag = true is much easier to read and understand.
In terms of syntax design, C++‘s names are case sensitive and does not specify a length limit on
names which increases readability. For example, aRealVariableName is much easier to read than
AREALVARIABLENAME. The use of upper case letters also helps identifiers to stand out in the code and
improves its readability. C++ has very good control structures, more flexible iteration statements and
data type structures which help its readability. The abstraction data types in C++ make program easier to
understand as abstraction increases expressivity and it ignores details and allows code to be re-used. In
C++, the use of OOP also improves its readability of complicated concepts. Furthermore, C++’s
enumeration types improve both readability and reliability because named values are easily to
understand than coded values (Sebesta, 2008).
3.2 Writability
Writability is the measure of how easily a language can be used to create programs for a chosen
problem domain (Sebesta, 2008). Writability is highly associated with readability which means if the
language boosts good readability also has decent writability. However, it is easier to write programs in
C++ than to read programs written in C++. The reasons are C++ has rich data types and supports
Page | 19
abstraction which improves its writability. C++ also has efficient expressivity provided by a rich set of
operators which allows the programmers to solve the different/difficult problems with a very small
program making it very writable. The powerful operator “++” makes variable increment written very
convenient. For example, compare the notation count++ with count = count + 1, the former is more
convenient than latter expression. C++ has very powerful, flexible and efficient control statements which
improves its writability for solving complicated problems. C++ supports generic types, such as template,
which has its advantage for improving writability.
3.3 Reliability
A reliable program performs to its specifications under all conditions. Reliability typically isn’t
considered per problem domain. Syntax design, type checking, exception handling, aliasing, readability
and writability are major factors that affect a program’s reliability.
C++ is a dominant object-oriented programming language and it is reliable if a programmer uses
it carefully. For example, if C++ programmers use the string class from the standard library rather than
char arrays and the C string library it will make program more reliable; otherwise, it could cause
numerous errors. Because C++ focuses on flexibility and efficiency more than reliability, it is not a
strongly typed and it does not have strict type checking which could reduce its reliability to some degree
based on the facts that C++ supports unions type and it is an unsafe construct. C++ has a very powerful
pointer data type which can be used to access address directly and its use is extremely flexible. The
trade-off of using pointer is that a dangling pointer and memory leakage could occur which affects its
reliability greatly. As an OOP language, C++ supports abstraction and information hiding which improves
its reliability.
Page | 20
C++ offers a comprehensive exception handling system which uses the try and catch blocks and
it can catch runtime errors, fix the problem and continue the program. The exception handling improves
its reliability.
Aliasing means two or more distinct referencing names or methods for the same memory cell.
Aliasing reduces a program’s reliability. For example, consider the statements int x = 7 and int *y = &x,
both refer to the same memory cell. C++ allows aliasing because its designer trades a decrease in
reliability for an increase in efficiency and flexibility.
The reliability increases if a program has a better readability and writability. As mentioned in 3.1
and 3.2 C++ generally has more advantages in both readability and writability than disadvantages
combined with its flexibility and efficiency for complicated software development. Based on this point,
C++ is a reliable language.
3.4 Cost
It is difficult to evaluate the cost of C++ as the total cost of C++ contains many factors: training
programmers, writing programs, compiling programs, executing program, language implementation
system, poor reliability and maintenance.
C++ is a large language with a lot of features. It is difficult to learn. It may take a few months to
learn major features in order to be able to write a middle-level program for a new programmer. The cost
of writing programs depends on the particular applications. In general, its readability and writability is
fair as C++ has very straightforward syntax. In addition, C++ is directly developed from C language and it
is almost completely backward compatible with C which reduces a lot of cost for those programmers
who already know C very well. Currently, the cost on training programmer to learn and write C++ has
significantly dropped with cheaper or free C++ development environment.
Page | 21
Because C++ has inexpensive compliers and C++ uses compiler implementation method, it
decreases the total cost on both compilation and execution of the programs. C++ designing goals
emphasize flexibility and efficiency and it does not require run-time type checking which speeds up code
execution.
C++ is considered relatively unreliable compared with other languages such as Java. It may
increase some cost on the reliability and maintenance. However, it may cost more to ensure greater
reliability. And trade-offs mean it may decrease other cost with the cost of reliability maintenance. For
example, C++ does not check index ranges of arrays as the trade-off, it increases execution speed and it
is necessary in many C++ applications because system execution speed has higher priorities. C++’s syntax
and constructs style also improve its maintainability.
Overall, C++ is a very large and complex language. The total cost is fair and acceptable.
4. Bibliography and Reference
Deitel, Paul and Deitel Harvey, 2012. C++ How to Program, 8th Edition. Pearson Education Inc.
Horstmann, Cay, 2010. C++ for Everyone, 2nd Edition. John Wiley & Sons, Inc.
Olsson, Mikael, C++ Quick Syntax Reference, The expert’s Voice. Apress®
Pitt-Francis, Joe and Whiteley, Jonathan, 2012, Guide to Scientific Computing in C++, Springer-
Verlag.
Prata, Stephen, 2012. C++ Primer Plus, 6th Edition. Pearson Education Inc.
Sebesta, W. Robert, 2008. Concepts of Programming Languages, 10th Edition. Pearson Education
Inc.
Stroustrup, Bjarne, 2013. The C++ Programming Language, 4th Edition. Pearson Education Inc.
https://isocpp.org/