Thinking in C++ Notes(9)
chapter 9: Inline function
2 problems with preprocessor macros:
- a macro looks like a function call, but doesn't always act like one.
- the preprocessor has no permission to access class member data. This means preprocessor macros can not be used as class member functions.
Processor pitfalls:
- expression may expand inside the macro so that their evaluation precedence is different from what you expect.
for example,
#define FLOOR(x,b) x>=b?0:1
...
if(FLOOR(a&0x0f,0x07))
/* the macro will expand to */
if(a&0x0f>=0x07?0:1)
/* the precedence of & is lower than >=. */
/* you can solve this problem by putting parentheses around everything in the macro definition. */
#define FLOOR(x,b) (x)>=(b)?0:1 - every time you use an argument in a macro, that argument is evaluated. so if the evaluation of an argument has side effects, then the result can be surprising and will definitely not mimic function behavior.
#define BAND(x) (x)>5?(x):0
/* after you call BAND(a++), a will be a+1 or a+2 */
Inline function
- any function defined within a class body is automatically inline.
- you will almost always want to put inline definitions in a header file.
- you must include the header file containing the function and its definition in every file where the function is used.
- you'd better not inline a big function.
- the compiler cannot perform inlining if:
- the function is too complicated.(has any sort of looping)
- the address of the function is taken implicitly or explicitly
More preprocessor features:
- stringizing: using # directive can turn an identifier into a character array.
- string concatenation: two adjacent character arrays combine when they have no intervening punctuation.
#define DEBUG(x) cout<<#x" = "<<x<<endl
- token pasting: using ## directive allows you take two identifiers and paste them together to create a new identifier.
#define FIELD(a) char* a##_string; int a##_size
Last modified on 2007-06-12