Declaring symbols as `json_weak` shouldn't be mandatory.
It's pretty strange that this library defines all the weak symbols that it does. I can't think of a good reason for it, and I can think of many downsides... ideally there would be a way to turn that off, at the very least.
Have you got a usecase where this affects you?
It's there so that it works as a single header (the alternative being doing what STB libs do and have a single C file you need to define an implementation macro in).
Have you got a usecase where this affects you?
It's there so that it works as a single header (the alternative being doing what STB libs do and have a single C file you need to define an implementation macro in).
The STB way is much cleaner and allows easier integration into any codebase!
I use the STB pattern in all my single-header-file libraries and it works great.
- You can use it as static, so its visible to a translation unit only
- You can use it as extern, so using in other translation units is possible
- You can use it as export/import for static libraries
- You can use it as a external library, either statically/dynamically linked or or by runtime linking
When you want to support all of that, you basically have to define your own storage classifiers, such as api/static/extern/export/import, etc.
Every public function uses the api storage classifier, such as json_api or json_public, whatever you prefer and internal functions uses json_internal which maps directly to static.
If you want to see a full block of a well written single-header-file-library that uses that pattern in its full potential:
/**
* @defgroup StorageClassIdents Storage class identifiers
* @brief This category contains storage class identifiers, such as static, extern, inline, etc.
* @{
*/
//! Global persistent variable
#define fpl_globalvar static
//! Local persistent variable
#define fpl_localvar static
//! Private/Internal function
#define fpl_internal static
//! Inline function
#define fpl_inline inline
//! Internal inlined function
#define fpl_internal_inline inline
//! External call
#if defined(FPL_IS_CPP)
# define fpl_extern
#else
# define fpl_extern extern
#endif
//
// DLL Export/Import definition
//
#if defined(_WIN32) || defined(__CYGWIN__)
# ifdef __GNUC__
# define fpl__m_dllexport __attribute__ ((dllexport))
# define fpl__m_dllimport __attribute__ ((dllimport))
# else
# define fpl__m_dllexport __declspec(dllexport)
# define fpl__m_dllimport __declspec(dllimport)
# endif
# define fpl__m_dlllocal
#else
# if __GNUC__ >= 4
# define fpl__m_dllimport __attribute__((visibility("default")))
# define fpl__m_dllexport __attribute__((visibility("default")))
# define fpl__m_dlllocal __attribute__((visibility("hidden")))
# else
# define fpl__m_dllimport
# define fpl__m_dllexport
# define fpl__m_dlllocal
# endif
#endif
/**
* @def fpl_dllimport
* @brief Link-library Import.
*/
#define fpl_dllimport fpl__m_dllimport
/**
* @def fpl_dllexport
* @brief Link-library Export.
*/
#define fpl_dllexport fpl__m_dllexport
/**
* @def fpl_dlllocal
* @brief Link-library Local.
*/
#define fpl_dlllocal fpl__m_dlllocal
//
// API Call
//
#if defined(FPL_API_AS_PRIVATE)
# define fpl__m_api static
#elif defined(FPL_DLLEXPORT)
# define fpl__m_api fpl_dllexport
#elif defined(FPL_DLLIMPORT)
# define fpl__m_api fpl_dllimport
#else
# define fpl__m_api fpl_extern
#endif // FPL_API_AS_PRIVATE
/**
* @def fpl_api
* @brief API call.
*/
#define fpl_api fpl__m_api
#if defined(FPL_IS_CPP)
# define fpl__m_platform_api extern "C" fpl_api
# define fpl__m_common_api extern "C" fpl_api
#else
# define fpl__m_platform_api fpl_api
# define fpl__m_common_api fpl_api
#endif
/**
* @def fpl_platform_api
* @brief Platform API.
*/
#define fpl_platform_api fpl__m_platform_api
/**
* @def fpl_common_api
* @brief Common API.
*/
#define fpl_common_api fpl__m_common_api
/** @} */
That's great that it works for you. My way works for me :)