5.10.1.  Inlining Versus Macro Expansion

[ fromfile: functions.xml id: inlinevsmacro ]

#define MACRO_ID expr
   

Example 5.19. src/functions/inlinetst.cpp

// Inline functions vs macros

#include <iostream>
#define  BADABS(X)   (((X) < 0)? -(X) : X)
#define  BADSQR(X) (X * X)
#define  BADCUBE(X) (X) * (X) * (X)

using namespace std;

inline double square(double x) {
    return x * x ;
}

inline double cube(double x) {
    return x * x * x;
}

inline int absval(int n) {
    return (n >= 0) ? n : -n;
}

int main() {
    cout << "Comparing inline and #define\n" ;
    double  t = 30.0;
    int i = 8, j = 8, k = 8, n = 8; 
    cout << "\nBADSQR(t + 8) = " << BADSQR(t + 8) 
            << "\nsquare(t + 8) = " << square(t + 8)
            << "\nBADCUBE(++i) = " << BADCUBE(++i)
            << "\ni = " << i
            << "\ncube(++j) = " << cube(++j)
            << "\nj = " << j
            << "\nBADABS(++k) = " << BADABS(++k)
            << "\nk = " << k
            << "\nabsval(++n) = " << absval(++n)
            << "\nn = " << n << endl;
}


Comparing inline and #define

BADSQR(t + 8) = 278
square(t + 8) = 1444
BADCUBE(++i) = 1100
 i = 11
cube(++j) = 729
j = 9
BADABS(++k) = 10
k = 10
absval(++n) = 9
n = 9

BADSQR(t+8) gives the wrong results because

    BADSQR(t + 8)
=   (t + 8 * t + 8)         (preprocessor)
=   (30.0 + 8 * 30.0 + 8)   (compiler)
=   (30 + 240 + 8)          (runtime)
=   278
     BADCUBE(++i)
=   ((++i) * (++i)) * (++i)   // left associativity 
=   ((10) * (10)) * (11)
=   1100
  1. #ifndef/#define/#endif wrapping around header files to avoid multiple inclusion

  2. #ifdef/#else/#endif to conditionally compile some parts of code but not others

  3. __FILE__ and __LINE__ macros for debugging and profiling

  4. In Qt, macros are used with code-generation to add dynamic features to QObjects, such as properties, signals and slots.