Read about <stdarg.h>
and variadic functions. On Linux, see also stdarg(3). It is how you can define in C such functions of variable arity (like printf
). The first few arguments should be fixed, and of known type, so you cannot have exactly what you want (with a call like function()
without arguments). So a variadic function is required to have at least one first fixed-type argument (which usually determines, like in printf
, the type and number of following variadic arguments). So the C language specification forbids to call the same function
without any arguments and with two of them.
Be also aware of the ABI of your system. It defines calling conventions (which usually vary with the signature of the called function) For 64 bits x86 on Linux, see this (floating point and pointer arguments get passed in different registers).
GCC (specifically) has also builtins for constructing function calls, but the C11 standard n1570 don't have anything like that.
It is unclear what you exactly want to achieve, but in some cases you might generate code (e.g. pedantically use metaprogramming) at runtime. There are several ways to achieve that on Linux:
You could generate (in a file) some C code in /tmp/emittedcode.c
, fork its compilation as a plugin (by running gcc -fPIC -shared -Wall -O -g /tmp/emittedcode.c -o /tmp/generatedplugin.so
) then load that plugin using dlopen(3) (as void*dlh = dlopen("/tmp/generatedplugin.so", RTLD_NOW);
but you should handle failure) and dlsym(3) of symbols there. My manydl.c example shows that you can practically do that for many hundred thousands of generated plugins.
You could use some JIT-compiling library like libgccjit or asmjit or libjit, or GNU lightning, etc...
In both cases, you'll then (conceptually) add a new code segment to your process and get the address of a freshly created function there into some function pointer.
Be also aware of closures and anonymous functions, and notice that C don't have them (but have to use callbacks). Read SICP.
As commented by Antti Haapala, look also into libffi (it enables you to call an arbitrary function with arbitrary arguments by "interpreting" that call, which you would describe by ad-hoc data structures).