I l @ ve RuBoard |
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. |
I l @ ve RuBoard |