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?)
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.