Selections in C++: Common Errors and Pitfalls

Forgetting necessary braces, misplacing semicolons in an if statement, mistaking ==for =, and dangling else clauses are common errors in selection statements. Duplicated statements in if-else statements and testing equality of double values are common pitfalls.

Common Error 1: Forgetting Necessary Braces

The braces can be omitted if the block contains a single statement. However, forgetting the braces when they are needed for grouping multiple statements is a common programming error. If you modify the code by adding new statements in an if statement without braces, you will have to insert the braces. For example, the following code in (a) is wrong. It should be written with braces to group multiple statements, as shown in (b).

In (a), the console output statement is not part of the if statement. It is the same as the following code:

Regardless of the condition in the if statement, the console output statement is always executed.

Common Error 2: Wrong Semicolon at the if Line

Adding a semicolon at the end of an if line, as shown in (a) below, is a common mistake.

This mistake is hard to find, because it is neither a compile error nor a runtime error; it is a logic error. The code in (a) is equivalent to that in (b) with an empty body.

Common Error 3: Mistakenly Using = for ==

The equality testing operator is two equal signs (==). In C++, if you mistakenly use = for ==, it will lead to a logic error. Consider the following code:

if (count = 3)

cout << “count is zero” << endl;

else

cout << “count is not zero” << endl;

It always displays “count is zero”, because count = 3 assigns 3 to count and the assignment expression is evaluated to 3. Since 3 is a nonzero value, it is interpreted as a true condition by the if statement. Recall that any nonzero value evaluates to true and zero value evaluates to false.

Common Error 4: Redundant Testing of Boolean Values

To test whether a bool variable is true or false in a test condition, it is redundant to use the equality testing operator like the code in (a):

Instead, it is better to test the bool variable directly, as in (b). Another good reason for doing this is to avoid errors that are difficult to detect. Using the = operator instead of the == operator to compare equality of two items in a test condition is a common error. It could lead to the following erroneous statement:

if (even = true)

cout << “It is even.”;

This statement assigns true to even so that even is always true. So, the condition for the if statement is always true.

Common Error 5: Dangling else Ambiguity

The code in (a) below has two if clauses and one else clause. Which if clause is matched by the else clause? The indentation indicates that the else clause matches the first if clause. However, the else clause actually matches the second if clause. This situation is known as the dangling else ambiguity. The else clause always matches the most recent unmatched if clause in the same block. So, the statement in (a) is equivalent to the code in (b).

Since (i > j) is false, nothing is displayed from the statements in (a) and (b). To force the else clause to match the first if clause, you must add a pair of braces:

int i = 1, j = 2, k = 3;

if (i > j)

{

if (i > k)

cout << “A”;

}

else

cout << “B”;

This statement displays B.

Common Error 6: Equality Test of Two Floating-Point Values

As discussed in Common Error 3 in Section 2.16, floating-point numbers have limited precision and calculations involving floating-point numbers can introduce round-off errors. Therefore, an equality test of two floating-point values is not reliable. For example, you expect the following code to display x is 0.5, but surprisingly it displays x is not 0.5.

double x = 1.0 – 0.1 – 0.1 – 0.1 – 0.1 – 0.1;

if (x == 0.5)

cout << “x is 0.5” << endl;

else

cout << “x is not 0.5” << endl;

Here, x is not exactly 0.5, but is very close to 0.5. You cannot reliably test the equality of two floating-point values. However, you can compare whether they are close enough by testing whether the difference of the two numbers is less than some threshold. That is, two numbers x and y are very close if | x – y \ < ε, for a very small value, ε. ε, a Greek letter pronounced epsilon, is commonly used to denote a very small value. Normally, you set e to 10-14 for comparing two values of the double type and to 10-7 for comparing two values of the float type. For example, the following code

const double EPSILON = 1E-14;

double x = 1.0 – 0.1 – 0.1 – 0.1 – 0.1 – 0.1;

if (abs(x – 0.5) < EPSILON)

cout << “x is approximately 0.5” << endl;

will display that

x is approximately 0.5

The abs(a) function in the cmath library file can be used to return the absolute value of a.

Common Pitfall 1: Simplifying Boolean Variable Assignment

Often, new programmers write the code that assigns a test condition to a bool variable like the code in (a):

This is not an error, but it should be better written as shown in (b).

Common Pitfall 2: Avoiding Duplicate Code in Different Cases

Often, new programmers write the duplicate code in different cases that should be combined in one place. For example, the highlighted code in the following statement is duplicated:

if (inState)

{

tuition = 5000;

cout << “The tuition is ” << tuition << endl;

}

else

{

tuition = 15000;

cout << “The tuition is ” << tuition << endl;

}

This is not an error, but it is better to write it as follows:

if (inState)

{

tuition = 5000;

}

else

{

tuition = 15000;

}

cout << “The tuition is ” << tuition << endl;

The new code removes the duplication and makes the code easy to maintain, because if the print statement is modified you only need to change in one place.

Common Pitfall 3: Integer Values Can Be Used as Boolean Values

In C++, a Boolean true is treated as 1 and false as 0. A numeric value can be used as a Boolean value. In particular, C++ converts a nonzero value to true and 0 to false. A Boolean value can be used as an integer. This may lead to potential logic errors. For exam­ple, the following code in (a) has a logic error. Assume amount is 40, the code will display Amount is more than 50, because lamount evaluates to 0 and 0 <= 50 is true. The correct code should be as shown in (b).

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *