builtin.c: typecheck builtin cfunctions in function_list #3209
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In C23 (default C standard used by GCC 15),
jv (*fptr)();
has become equivalent tojv (*fptr)(void);
so we can no longer assign builtin implemenations directly to thefptr
member ofcfunctions
without generating a compile error.Since there does not seem to be any straight-forward way to tell autoconf to force the compiler to use C99 short of explicitly adding -std=c99 to CFLAGS, it is probably a cleaner solution to just make the code C23 compatible.
A possible solution could have been to just redeclare
cfunction.fptr
asvoid*
, but then the functions' return type would not have been type checked (e.g. if you tried to add a{printf, "printf", 2}
, where printf is a function that does not return jv, the compiler wouldn't have complained.)We were already not typechecking the arguments of the functions, so e.g.
compile without errors despite not having the correct prototype.
So I thought of instead improving the situation by redefining
cfunction.fptr
as a union of function pointers with the prototypes that the jq bytecode interpreter can call, and use a macro to add the builtin functions tofunction_list
using to the arity argument to assign the implementation function to the appropriate union member.Now the code won't compile if the wrong arity, or an arity not supported by the bytecode interpreter (>5 = 1input+4arguments), or a prototype not jallable by the bytecode interpreter (e.g.
binop_plus
that doesn't expect ajq_state*
argument).Also, the code now compiles with gcc -std=c23.
Fixes #3206