ibireme / yyjson

The fastest JSON library in C
https://ibireme.github.io/yyjson/doc/doxygen/html/
MIT License
3.04k stars 262 forks source link

Define YYJSON_DISABLE_UTILS makes symbol not found #177

Closed starwing closed 1 month ago

starwing commented 1 month ago

Describe the bug I'm writing a Lua binding for yyjson, and I find if I define YYJSON_DISABLE_UTILS like this:

 #define YYJSON_DISABLE_UTILS 1
#define yyjson_api static
#include "yyjson.h"
#include "yyjson.c"

the link errs like this:

|| In file included from lyyjson.c:19:
yyjson.h|7093 col 24| warning: 'unsafe_yyjson_ptr_getx' used but never defined
||  7093 | yyjson_api yyjson_val *unsafe_yyjson_ptr_getx(yyjson_val *val,
||       |                        ^~~~~~~~~~~~~~~~~~~~~~
yyjson.h|7098 col 28| warning: 'unsafe_yyjson_mut_ptr_getx' used but never defined
||  7098 | yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_getx(yyjson_mut_val *val,
||       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~
yyjson.h|7105 col 17| warning: 'unsafe_yyjson_mut_ptr_putx' used but never defined
||  7105 | yyjson_api bool unsafe_yyjson_mut_ptr_putx(yyjson_mut_val *val,
||       |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
yyjson.h|7114 col 28| warning: 'unsafe_yyjson_mut_ptr_replacex' used but never defined
||  7114 | yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_replacex(
||       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
yyjson.h|7119 col 28| warning: 'unsafe_yyjson_mut_ptr_removex' used but never defined
||  7119 | yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_removex(yyjson_mut_val *val,
||       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Your environment

starwing commented 1 month ago

(btw, I found another warning when use yyjson_inline_api as yyjson_api:

yyjson.c|6296 col 37| warning: pointer 'val_hdr' may be used after 'realloc' [-Wuse-after-free]
||  6296 |         val = val_tmp + (usize)(val - val_hdr); \
||       |                                     ^
yyjson.c|6358 col 5| note: in expansion of macro 'val_incr'
||  6358 |     val_incr();
||       |     ^~~~~~~~
|| In function 'default_realloc',

)

ibireme commented 1 month ago

The first warning happens because the definition of yyjson_api is changed.

The original code is like this, and it's fine:

extern void foo(void);
static inline void bar(void) {
    foo();
}

But when you #define yyjson_api static, it changes extern to static, causing a warning:

static void foo(void);
static inline void bar(void) {
    foo();
}

The second warning comes from including yyjson.c directly.

In yyjson.c, alc.realloc() is used to call realloc indirectly through a function pointer. Normally, yyjson.c is compiled separately, so there's no warning.

But if you compile yyjson.c with your code in one unit and don't use a custom allocator, GCC will perform constant propagation and inline alc.realloc() to libc's realloc(), which causes the warning.


Could you share more about why you're using the library this way?

starwing commented 1 month ago

I'm just trying to make a single DLL module on windows for Lua, in this way unused functions are stripped from the result binary, and all routes are inlined for better performance and binary size.

The first warning also makes link failure for missing symbols.

It seems that what I needed is something like yyjson_static_api.

The binding code is here: https://github.com/starwing/luabuild/blob/master/src/lyyjson.c

(Notice that all sources including Lua are amalgamated into one translation unit in one.c)

ibireme commented 1 month ago

Fixed.