More C++ Idioms/Inline Guard Macro

Inline Guard Macro

edit

Intent

edit

To conveniently control inline-ness of functions using a compiler command line macro definition switch.

Also Known As

edit

Motivation

edit

For debugging purpose, it is often necessary to turn off inlining of functions throughout the program. But for release version, inline functions are desirable. This indicates a need of a quick way of turning inline-ness on/off as and when desired. Moreover, such functions should be defined in header files when they are inlined and otherwise should be in the source (.cpp) file. If non-inline functions are in header files, almost always it ends up creating multiple definitions of the function. On the other hand, if inline functions are not in header files then compilation units can't find them. In both the cases linker throws errors.

Therefore, a flexible way of inlining is often desirable but C++ language does not support it without some macro magic. The Inline Guard Macro idiom achieves this.

Solution and Sample Code

edit

The solution is to put all the inline functions in a separate file called .ipp file and decorate each function with a macro INLINE. Header file and the implementation file is create as usual and the .ipp file in selectively included in one of the two files (header or implementation) depending upon whether inlining is desired. An example of a class Test is given below.

// test.ipp file
INLINE void Test::func()
{}


// test.hpp file
#ifndef MYPROJECT_TEST_H // Note include guards.
#define MYPROJECT_TEST_H 

class Test
{
  public:
    void func();
};

#ifdef MYPROJECT_INLINE_ENABLED
#define INLINE inline // Define INLINE as inline (the keyword)
#include "test.ipp"   // It is included only when MYPROJECT_INLINE_ENABLED is defined, i.e. inlining is enabled.
#endif

#endif  // MYPROJECT_TEST_H


//test.cpp file
#include "test.hpp" // Include header file as usual.

#ifndef MYPROJECT_INLINE_ENABLED
#define INLINE      // INLINE is defined as empty string
#include "test.ipp" // It is included only when MYPROJECT_INLINE_ENABLED is NOT defined, i.e. inlining is disabled.
#endif

The effect of using Include Guard Macro is that depending upon whether MYPROJECT_INLINE_ENABLED is defined or not, test.ipp gets #included in either test.cpp or test.hpp. When it gets merged with test.cpp, functions are not inlined because INLINE is defined as an empty string. On the other hand when test.ipp is merged with test.hpp, INLINE is defined as inline (the keyword).

Now, what remains is to define the MYPROJECT_INLINE_ENABLED macro when desired. Generally, all modern C/C++ compilers allow defining macros at command line. For example to compile the above program on gcc using inlining, the argument -DMYPROJECT_INLINE_ENABLED option is added to the compiling command line. If no such macro is defined, the functions are automatically treated as non-inline and the program compiles OK.

Known Uses

edit
  • ACE (Adaptive Communication Environment)
  • TAO (The ACE ORB)
edit