c++cinlineheader-only

Difference between inlining and including source through macro


I've spent some time developing a header-only library and have stumbled across a crossroads. Everywhere I look on the web, inline functions are always used. But in the example of stb_image.h, the source code is just written in the bottom half of the header surrounded by a #ifdef STB_IMAGE_IMPLEMENTATION like so:

#ifndef STB_IMAGE_H_INCLUDED_
#define STB_IMAGE_H_INCLUDED_

void some_func(args);

#endif // STB_IMAGE_H_INCLUDED_

#ifdef STB_IMAGE_IMPLEMENTATION

void some_func(args) {
    // implementation
}

#endif // STB_IMAGE_IMPLEMENTATION;

Then a (preferably source that isn't main.cpp) file defines a macro with the same name and includes the header right after like so:

#include <…>
#include <…>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

// other code

Why would you use one over the other? (or rather why does stbi do this at all?)


Solution

  • STB is a C library. C inline was introduced in C99, and don't work like C++ inline. C inline still must be implemented in one translation unit only.

    C++ inline is used to make exception in the ODR rule, and allow multiple implementation as long as they are the same.

    STB wants to be a header only library, but they don't really exist in C, so they used a macro based solution to only implement the code in a choosen translation unit.