10.8 Answers to Chapter Questions
Answer 10-1: After the program has been run through the preprocessor, the
std::cout statement is expanded to look like:
std::cout << "The square of all the parts is " << 7 + 5 * 7 + 5 << '\n';
The equation 7 + 5 * 7 + 5 evaluates to 47. It is a good rule to put
parentheses ( ) around all expressions in macros. If you change the
definition of ALL_PARTS to:
#define ALL_PARTS (FIRST_PART + LAST_PART)
the program executes correctly.
Answer 10-2: The preprocessor is a very simple-minded program. When it defines a
macro, everything past the identifier is part of the macro. In this
case, the definition of MAX is literally
=10. When the for
statement is expanded, the result is:
for (counter==10; counter > 0; --counter)
C++ allows you to compute a result and throw it away. For this
statement, the program checks to see whether
counter is 10 and discards the answer. Removing
the = from the macro definition will correct the
problem.
Answer 10-3: As with the previous problem, the preprocessor does not respect C++
syntax conventions. In this case, the programmer used a semicolon to
end the statement, but the preprocessor included it as part of the
definition for size. The assignment statement for
size, expanded, is:
size = 10; -2;;
The two semicolons at the end do not hurt anything, but the one in
the middle is a killer. This line tells C++ to do two things: assign
10 to size and compute the value -2 and throw it
away (this results in the null effect warning). Removing the
semicolons will fix the problem.
Answer 10-4: The output of the preprocessor looks like:
int main( ) {
int value;
value = 1;
if (value < 0)
std::cout << "Fatal Error: Abort\n"; exit(8);
std::cout << "We did not die\n";
return (0);
}
The problem is that two statements follow the if line. Normally they would be put on two
lines. If we properly indent this program we get:
Example 10-10. die3/die.cpp
#include <iostream>
#include <cstdlib>
int main( ) {
int value; // a random value for testing
value = 1;
if (value < 0)
std::cout << "Fatal Error:Abort\n";
exit(8);
std::cout << "We did not die\n";
return (0);
}
From this it is obvious why we always exit. The fact that there were
two statements after the if was
hidden by using a single preprocessor macro. The cure for this
problem is to put curly braces around all multistatement macros.
#define DIE \
{std::cout << "Fatal Error: Abort\n"; exit(8);}
Answer 10-5: The problem is that the preprocessor does not understand C++ syntax.
The macro call:
SQR(counter+1)
expands to:
(counter+1 * counter+1)
The result is not the same as ((counter+1) *
(counter+1)). To avoid this problem, use inline functions
instead of parameterized macros:
inline int SQR(int x) { return (x*x);}
If you must use parameterized macros, enclose each instance of the
parameter in parentheses:
#define SQR(x) ((x) * (x))
Answer 10-6: The only difference between a parameterized macro and one without
parameters is the parentheses immediately following the macro name.
In this case, a space follows the definition of
RECIPROCAL, so it is not a parameterized macro.
Instead it is a simple text replacement macro that replaces
RECIPROCAL with:
(number) (1.0 / number)
Removing the space between RECIPROCAL and
(number) corrects the problem.
|