I've got a bunch of C functions which get assigned to an array of function pointers, along the lines of this:
typedef int (*func)(int);
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
func f[] = { SomeLongName1, ... , SomeLongName1000 };
This is a lot of work to create and is prone to errors. For instance, there could be a typo in the function name such that a valid function is still named, but the wrong one. Or, if a new function is added at the end one could forget to go in and explicitly add it to the list of function pointers as well.
In order to avoid having to explicitly declare the array of function pointers I have tried various tricks such as macros, which make the code hard to understand and require knowing how the macro works, and I am generally unsatisfied with them.
What I would like to do is something like this:
typedef int (*func)(int);
func f[] = {
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
};
This way, the array would be automatically created, and if there was some way to put a null pointer at the end so I can determine how many function pointers there are that would be great as well.
However, the above isn't valid C and I'm coming up empty with any way of accomplishing this. If it is something compiler specific (e.g. a GCC extension) that would be ok.
All the functions are statically known at compile time, so I would like to avoid having to do any run-time initialization of the function pointer array - not that I have found a method to do it that way either.
This related question How to define an array of functions, seems to ask the same question, but does not carry it to its logical conclusion. Specifically, I don't want to have to re-type anything I have already typed so as to save time and avoid errors.
If you don't care about the order of functions in the array, and are willing to use a GCC extension, then you can achieve what you want using a whole bunch of initializer (constructor) functions. This obviously isn't ideal because of the sheer number of extra functions defined, but it is certainly one approach you can consider. It constructs the array at runtime.
Define the function append to append a single function to an array (reallocating if needed). Then, the code is basically
#define ARRAYFUNC(name) int name(int); \
void __attribute__((constructor)) __init_##name(void) { append(func); } \
int name(int a)
ARRAYFUNC(func1) {
...
}
ARRAYFUNC(func2) {
...
}
You could use the C preprocessor (X-Macros) for this:
#include <stdio.h>
// define a list of function names and bodies
#define FUNCS \
FUNC(add, { return a+b; }) \
FUNC(mul, { return a*b; }) \
FUNC(div, { return a/b; })
// let the preprocessor make up the actual function implementations
#define FUNC(name, body) int name(int a, int b) body
FUNCS
#undef FUNC
typedef int (*func)(int, int);
// let the preprocessor populate the array of function pointers
func f[] = {
#define FUNC(name, body) name,
FUNCS
#undef FUNC
};
// use it:
int main () {
int a = 2, b = 3, i = 0;
for (; i < sizeof(f)/sizeof(*f); i++) {
printf("%d\n", f[i](a,b));
}
return 0;
}
The output is:
$ gcc test.c && ./a.out
5
6
0
What I would use to solve such a situation (only if I can't avoid it, of course), is to use preprocessing. Not the one available from the C preprocessor, it does not provide the required functionality in a sensible syntax, but a really powerful one like m4.
With m4, your code could look like this:
define(`functionList', `, 0')
define(`functionArrayMember', `define(`functionList', `$1, 'FunctionList)$1')
define(`buildFunctionArray', `{ functionList }')
int functionArrayMember(SomeLongName1)(int a) {
return a+1;
}
//...
int functionArrayMember(SomeLongName1000)(int a) {
return a+1;
}
func f[] = buildFunctionArray();
You just need to provide the right m4 definition for functionArrayMember() and buildFunctionArray(), and you have the functionality you need.
I do not think there is any other way of doing what want to do.
What you wrote
func f[] = { SomeLongName1, ... , SomeLongName1000 };
already does what is best.
Maybe you could name your functions with an prefix 0000 to 1000, so that you can be sure each function is in the right place in your functions pointer array.
Also, if you really have 1000 different functions, they are surely things in common that could lead you to sort them in several arrays, reducing the numbering effort, and that is less error prone.
Related
I am trying to have an array of arrays of function pointers, but cannot assign to it, only statically initialize it:
#define N_INPUTS 2
#define N_STATES 2
void one()
{
//do stuff
}
void two()
{
//do stuff
}
//etc.
typedef void (*action_map[N_INPUTS])();
action_map my_action_maps[N_STATES];
//this would work:
//action_map am1 = {one, two};
//action_map am2 = {two, one};
//action_map my_action_maps[N_STATES] = { am1, am2 };
void init()
{
action_map am1;
am1[0] = one;
am1[1] = two;
my_action_maps[0] = am1; //error "expression must be a modifiable lvalue"
//however this works:
my_action_maps[0][0] = one;
my_action_maps[0][1] = two;
}
//the idea is to then handle input depending on a state with
//my_action_maps[state][input]();
I am not sure why is this happening, my_action_maps is just an array of pointers to function pointers, isn't it? Why it can initialized with initializer but then it is not modifiable?
This isn't really about function pointers, they are just making it harder to see the issue.
The type action_map is an array of function pointers. am1 and my_action_maps[0] are both of that type. But in C, you cannot assign an array to another array. It's the same issue as this:
int a[3] = {1,2,3};
int b[3] = {4,5,6};
a = b; // error
Current versions of gcc and clang both give a more useful message that explicitly says the problem is assigning to an array type. You might consider switching or upgrading your compiler.
You need to copy the elements one by one with a loop, or with memcpy. Thanks to array-pointer decay, you could do:
memcpy(my_action_maps[0], am1, sizeof(action_map));
Alternatively, you could wrap your action_map type in a struct, since you can assign structs to one another. But then it's a little more awkward to access the members.
typedef struct {
void (*actions[2])();
} action_map;
action_map my_action_maps[2];
void init(void) {
action_map am1;
am1.actions[0] = one;
am1.actions[1] = two;
// or: action_map am1 = { { one, two } };
// or: action_map am1 = { one, two };
my_action_maps[0] = am1; // ok
}
By the way, regarding your function and type declarations using empty parentheses, I suggest reading func() vs func(void) in C99 and Is it better to use C void arguments "void foo(void)" or not "void foo()"?. It may look like typedef void (*action_map[N_INPUTS])(); declares an array of pointers to functions taking no arguments, but it actually declares an array of pointers to functions taking unspecified arguments. This is supported mostly for compatibility with old versions of C and should generally not be used in new programs.
If you do am1[0](1,2,3); you will not get a compile error, and the compiler will happily attempt to pass three arguments to the function one that is not supposed to take any. This is undefined behavior. On some platforms, they might just be ignored, but you won't be alerted that you probably meant something else. On other platforms this may crash or worse. For instance, on a system using a calling convention where the called function is supposed to pop the stack (like the stdcall convention on Windows 32-bit compilers), calling a function with the wrong number of arguments will corrupt the stack.
So a better choice would be
typedef void (*action_map[N_INPUTS])(void);
Then action_map am1; am1[0](1,2,3); will cause a compiler error.
For consistency, I think it is also best to use void when defining a function with no parameters, e.g. void one(void) { ... }.
I'm trying to implement a Python-like function decorator in C using function pointers but I'm getting weird segmentation fault error.
Idea is that we have a decorator function which has inner function wrapper. Decorator then takes some_function as an argument, puts it inside the wrapper along with additional code and returns the wrapper function.
Very simple function decorator in Python:
def decorator(f):
def wrapper():
#do something before
f()
#do something after
return wrapper
def some_func():
print('Hello')
some_func = decorator(some_func)
I know that Python, unlike C, treats functions as first class objects but I'm wondering if the same sort of functionality can be emulated in C by using function pointers.
I tried this
void* do_twice(void (*func)())
{
auto void wrapper()
{
func();
func();
}
return &wrapper;
}
void some_func()
{ printf("Hello\n"); }
int main()
{
void (*fun_ptr)() = &some_func;
fun_ptr = decorator(fun_ptr);
fun_ptr();
return 0;
}
Output
Hello
Segmentation fault
Now here is the funny bit. If I declare a variable inside wrapper like this:
auto void wrapper()
{
int blah=5;
func();
func();
}
Then segmentation fault is fixed. Can someone explain why is this so? Apparently I'm doing something wrong with the pointers and code is very unstable - seemingly unrelated additions to the main function will cause segmentation fault to pop again.
Do you allow me to have an excursion to C++? In this language, there are functor objects, these are kind of structs that can be called like a function:
struct Wrapper
{
/* this is what allows the struct to be called like a function: */
void operator()(/* can define arbitrary parameters here */)
{ /* some implementation */ }
};
In other words, this would allow you to write code like:
Wrapper w; // actually, C++ does more here than C, but that's out of
// scope of this question...
w(); // possible due to the operator() defined above
OK, now let's extend that a bit:
struct Wrapper
{
void(*m_f)(void); /* !!! */
void operator()(void) /* don't want any parameters... */
{
printf("before\n");
m_f();
printf("after\n");
}
};
Don't want to go any deeper, a C++ developer would now deal with accessibility (such that the member m_f can only be used inside the class) and would provide a so-called constructor (for initialising m_f member appropriately). With all that, the final C++ code using the wrapper class might look like:
Wrapper decorate(void(*f)(void))
{
return Wrapper(f); // the fore-mentioned constructor gets called
}
void test(void) { /* do something */ }
void demo(void)
{
Wrapper w = decorate(&test);
w();
}
Why that excursion? Well, have a close look at one specific line:
void(*m_f)(void);
Yes, there is a member variable! Python actually does something similar internally.
The 'problem' with C is that you cannot define your own function call operators. There's only the native one. So the big question is: Where to store the function pointer?
You could have a struct, storing the function pointer (analogously to the C++ solution), and pass that one to your own function emulating the function call operator. Actually, the C++ solution doesn't do anything else either, solely that all this is hidden behind syntactic sugar!
An equivalent C solution might look like this:
struct Wrapper
{
void(*m_f)(void);
};
void executeDecorated(Wrapper w)
{
printf("before\n");
w.m_f();
printf("after\n");
}
void demo(void)
{
Wrapper w = { &someFunction };
executeDecorated(w);
/* do whatever else ... */
executeDecorated(w);
}
This is probably the closest you can get in C (apart from that you might perhaps find better names).
If having a separate struct to store a function pointer brings you sufficient benefit or if you just want to pass the function pointer directly (executeDecorated(&someFunction), assuming the function was adjusted appropriately) is up to you to decide...
I have multiple functions that are similar to each other - they take in the same arguments, and return the same type:
double mathFunction_1(const double *values, const size_t array_length);
I already use typedef'd pointers to those functions, as I store them as an array to easily use any number of them on the same data, map them etc.:
typedef double (* MathFunction_ptr )(const double *, const size_t);
double proxy(MathFunction_ptr mathfun_ptr, const double *values, const size_t array_length);
What I want to achieve, is a similar ease-of-use with declaring and defining the functions, as I already have with using pointers to them.
Thus, I was thinking about using a similar typedef to make it easier for me to write the actual functions. I tried doing it like this:
// declaration
typedef double MathFunction (const double *values, const size_t array_length);
MathFunction mathFunction_2;
The following approach works partially. It lets me "save a few keystrokes" in the declaration, however the definition has to be fully typed out.
double mathFunction_2(const double *values, const size_t array_length)
{
// ...
}
What I found by searching more for this issue is this: Can a function prototype typedef be used in function definitions?
However it doesn't provide many alternatives, and only reaffirms that what I tried to do in my other experiments is forbidden according to the Standard. The only alternative it provides is using
#define FUNCTION(name) double name(const double* values, size_t array_length)
which sounds clunky to me(as I'm wary and skeptical of using the preprocessor).
What are the alternatives to what I'm trying to do?
Two other approaches I tried that don't work(and, as I just read, are forbidden and absolutely wrong according to the C standard 6.9.1):
1.This approach doesn't work, as it means that I'm telling it to define a variable mathFunction_2(I believe that variable is treated as a pointer, though I don't understand this well enough yet) like a function:
MathFunction mathFunction_2
{
// ...
}
2.This approach doesn't work, as it means I'm telling it to create a function which returns a function(unacceptable in the C language):
MathFunction mathFunction_2()
{
// ...
}
You could use a typedef for the signature (see also this):
typedef double MathFunction_ty (const double *, const size_t);
and then declare several functions of the same signature:
MathFunction_ty func1, func2;
or declare some function pointer using that:
MathFunction_ty* funptr;
etc... All this in C11, read n1570.
however the definition has to be fully typed out.
Of course, since you need to give a name to each formal parameter (and such names are not part of the type of the function) in the function's definition. Therefore
double func1(const double*p, const size_t s) {
return (double)s * p[0];
}
and
double func1(cont double*arr, const size_t ix) {
return arr[ix];
}
have the same type (the one denoted by MathFunction_ty above), even if their formal parameters (or formal arguments) are named differently.
You might abuse of the preprocessor and have an ugly macro to shorten the definition of such functions:
// ugly code:
#define DEFINE_MATH_FUNCTION(Fname,Arg1,Arg2) \
double Fname (const double Arg1, const size_t Arg2)
DEFINE_MATH_FUNCTION(func1,p,s) { return (double)s * p[0]; }
I find such code confusing and unreadable. I don't recommend coding like that, even if it is certainly possible. But sometimes I do code something similiar (for other reasons).
(BTW, imagine if C required every first formal argument to be named $1, every second formal argument to be named $2, etc...; IMHO that would make a much less readable programming langage; so formal parameter's name matters to the human reader, even if systematic names would make the compiler's life simpler)
Read also about λ-calculus, anonymous functions (C don't have them but C++ has lambda expressions), closures (they are not C functions, because they have closed values so mix code with data; C++ has std::function-s), callbacks (a necessary convention to "mimick" closures)... Read SICP, it will improve your thinking about C or C++. Look also into that answer.
Unfortunately in C I don't believe there is any way to do what you're asking without using preprocessor macros, and personally at least I agree with your assessment that they are clunky and to be avoided (though this is a matter of opinion and open to debate).
In C++ you could potentially take advantage of auto parameters in lambdas.
The example function signatures you show here really aren't complicated and I wouldn't worry about the perceived duplication. If the signatures were much more complicated, I would view this as a "code smell" that your design could be improved, and I'd focus my efforts there rather than on syntactic methods to shorten the declaration. That just isn't the case here.
Yes, you can. Indeed, that's the purpose of the typedef declaration, to use a type identifier to declare a type of variable. The only thing is that when you use such a declaration in a header file:
typedef int (*callback_ptr)(int, double, char *);
and then you declare something like:
callback_ptr function_to_callback;
it's not clear that you are declaring a function pointer and the number and type of the parameters, but despite of this, everything is correct.
Finally, I want to note you something particularly special. When you deal with something like this, it is normally far cheaper and quick to go to the compiler and try some example. If the compiler does what you want without any complaint, the most probable thing is that you are correct.
#include <stdio.h>
#include <math.h>
typedef double (*ptr_to_mathematical_function)(double);
extern double find_zero(ptr_to_mathematical_function f, double aprox_a, double aprox_b, double epsilon);
int main()
{
#define P(exp) printf(#exp " ==> %lg\n", exp)
P(find_zero(cos, 1.4, 1.6, 0.000001));
P(find_zero(sin, 3.0, 3.2, 0.000001));
P(find_zero(log, 0.9, 1.5, 0.000001));
}
double find_zero(
ptr_to_mathematical_function f,
double a, double b, double eps)
{
double f_a = f(a), f_b = f(b);
double x = a, f_x = f_a;
do {
x = (a*f_b - b*f_a) / (f_b - f_a);
f_x = f(x);
if (fabs(x - a) < fabs(x - b)) {
b = x; f_b = f_x;
} else {
a = x; f_a = f_x;
}
} while(fabs(a-b) >= eps);
return x;
}
The second, and main part of your question, if you are having such a problem, the only way you can solve it is via using macros (see how I repeated the above printf(3) function calls with similar, but not identical parameter lists, and how the problem is solved below):
#define MY_EXPECTED_PROTOTYPE(name) double name(double x)
and then, in the definitions, just use:
MY_EXPECTED_PROTOTYPE(my_sin) {
return sin(x);
}
MY_EXPECTED_PROTOTYPE(my_cos) {
return cos(x);
}
MY_EXPECTED_PROTOTYPE(my_tan) {
return tan(x);
}
...
that will expand to:
double my_sin(double x) {
...
double my_cos(double x) {
...
double my_tan(double x) {
...
you can even use it in the header file, like:
MY_EXPECTED_PROTOTYPE(my_sin);
MY_EXPECTED_PROTOTYPE(my_cos);
MY_EXPECTED_PROTOTYPE(my_tan);
As it has been pointed in other answers, there are other languages (C++) that give support for this and much more, but I think this is out of scope here.
I was wondering if it is possible in C (89/90) to chain function calls, and where it is defined in the C spec. I assume this isn't possible since a google search reveals no mention of it.
I thought of this because of a related conversation with a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement; instead, you have to assign the result of the function to a variable, and then manipulate the struct via the variable instead of directly from the function result itself. This leads me to believe that you can't chain functions either, but I can't seem to find these limitations discussed in the spec.
Edit : Sorry, I should have been specific on the return value. Assuming the function returns a function pointer, is it possible to dereference and call the result within the same statement, in fluent fashion?
For example, assuming getFunc returns a function pointer :
(*getFunc(getFuncParam))(otherFuncParam)
Or in the struct case, assuming a struct with an int member called count:
funcReturnsStruct(param).count++
Here's what function chaining looks like in C:
post_process(process(pre_process(data)));
Obviously, your friend is wrong. As long as the functions cooperate by accepting and returning the same type of value you can chain the calls all you like.
Contrast this with something like
data.pre_process().process().post_process();
The big difference is that in C (which has no encapsulation, hence no classes) functions have center stage while in more modern OO languages it's objects that get more attention.
Update: Sure it's possible to chain no matter what each function might return. For example:
int increase(int x) {
return x + 1;
}
typedef int (*increase_fp)(int);
increase_fp get_increase() {
return increase;
}
int main(void) {
printf("%d", get_increase()(1));
return 0;
}
See it in action.
a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement
Your friend is correct in the sense that the return value of a function cannot be the target of an assignment (it's not an lvalue). IOW, you can't do something like
int foo(void) { int x = 5; return x; }
...
foo() = 6;
However, if the return type of a function is a struct or a union, you can apply the component selection operator to the return value, such as
int x = foo().memb;
Similarly, if the return type of the function is a pointer to a struct or a union, you can write
int x = foo()->memb;
And if the return value is a pointer to another function, you can call that other function like so:
int bar(int x) { ... }
int (*foo)(int x) { return bar; }
int x = foo(x)(y); // or (*foo(x))(y) -- the result of foo(x) is
// called with the argument y
although anyone who has to maintain or debug your code may beat you severely for it.
What you cannot do is something like
foo().memb= ...;
foo()->memb = ...;
which wouldn't make sense anyway, because the lifetime of the value returned by foo ends when the statement ends - you wouldn't be able to retrieve that modified value.
Your friend is wrong.
If we have:
struct Point3
{
float x, y, z;
};
const Point3 * point3_get_origin(void);
then you can certainly do:
printf("the origin's y coordinate is %f\n", point3_get_origin()->y);
The function returns a value of the given type, so the call of the function can be used wherever such a value is needed in an expression.
Do you mean something like this?
typedef void (*CALLBACK)(void);
CALLBACK getCallback();
void test()
{
getCallback()();
}
It compiles with no warning in GCC 4.6.1 (default std).
There's a much faster and easier way to answer this than posting here: try it.
#include <stdio.h>
struct s {
int a;
} s;
struct s * getS() {
s.a = 13;
return &s;
}
int main(int argc, char * const argv[]) {
printf("%d\n", getS()->a);
return 0;
}
% gcc test.c -o test -Wall -pedantic
% ./test
13
%
Not so much as a pedantic warning. Expected output. Looks like it's perfectly fine. However, as has been pointed out, it would be better to store the return value and check for errors.
How do I approach a function echo_tpl that can take 1 parameter of type int or string ,and print it out?
C doesn't have templates. I think the best you could do is to use an union or to have the functions have different names. The latter way of having different names is the quasi-standard method of doing it (for instance fabs fabsf fabsl, also heavily used by OpenGL which also accounts for the fact C can't overload functions)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl_s("Hello world");
echo_tpl_i(42);
}
If there is a lot of common code, you may decide to factor it out in separate functions
void echo_tpl_s(char const *string) {
prepare_output_device();
printf("%s", string);
unprepare_output_device();
}
void echo_tpl_i(int number) {
prepare_output_device();
printf("%d", number);
unprepare_output_device();
}
Or you can take the union way, which will have the function names be equal but instead blow up the parameter type with meta informations.
enum Type {
Number,
String
};
struct Value {
enum Type type;
union {
int number;
char const *string;
} u;
};
void echo_tpl(struct Value value) {
switch(value.type) {
case Number: printf("%d", value.u.number); break;
case String: printf("%s", value.u.string); break;
}
}
int main(void) {
echo_tpl((struct Value) {
.type = String,
.u.string = "Hello world"
});
}
The union way is particular well-suited if you want to store the value somewhere and then execute the print function without caring what value type you pass to it. In C89 you would need to create the value separately since it doesn't have compound literals
int main(void) {
struct Value value;
value.type = String;
value.u.string = "Hello world";
echo_tpl(value);
}
It's a good idea to create functions for that, though
struct Value stringval(char const *string) {
struct Value value;
value.type = String;
value.u.string = string;
return value;
}
struct Value numberval(int number) {
struct Value value;
value.type = Number;
value.u.number = number;
return value;
}
int main(void) {
echo_tpl(stringval("Hello world!"));
}
Some compilers may provide extensions for writing such things. For instance Clang provides function overloading in C.
void echo_tpl(int value) __attribute__((overloadable)) {
printf("%d", value);
}
void echo_tpl(char const *value) __attribute__((overloadable)) {
printf("%s", value);
}
This solves the call-side of the function not to depend on the type. On the definition side, you still have to write the code twice. That's mainly because (as another answer explains) C doesn't have type-generic output functions. Of course if you use this feature, your code becomes nonportable.
The traditional way to translate templates to C is using the preprocessor. I'd do it something like this:
// this creates each template "instance"
#define ECHO_TPL_IMPLEMENT(t) void echo_tpl_##t(t param){\
/* this is where you write your function that uses param */ \
}
// this calls the specific template instance
#define ECHO_TPL(t, val) echo_tpl_##t(val)
// as i wrote it, the function only accepts a 1 word parameter type
// so for simplicity, i'm defining char* to be string
typedef char *string;
// i implement the function for the types int and string
ECHO_TPL_IMPLEMENT(int) // creates echo_tpl_int
ECHO_TPL_IMPLEMENT(string) // creates echo_tpl_string
main()
{
// then i just call them and let the preprocessor handle it
ECHO_TPL(string, "meep"); // will call echo_tpl_string
ECHO_TPL(int, 10); // will call echo_tpl_int
}
This is how the original C++ compilers handled templates, only they had (and still do to this day) more complex type mangling rules, where I just assumed types are 1 word and if they aren't, you'll have to typedef them.
edit: Note that I left the function empty. This is indeed how you write "templated functions" in C, but I cant really write the parameter like you asked because C doesn't have a type-independent file writing api. printf and write require information about the actual type (through the %d or %s and through the length in bytes of what to write respectively), and we don't have that.
Also note that this applies to C++ too. You can't use the C api to write to a file from a template either, you can only really use cout (or the boost format alternative or something similar). You'll have to think what you want to do with the actual function.
Late, but worth adding to this that as of the C11 standard, C now has some very limited support for overloading by using _Generic expressions, that select the right result expression at compile-time based on the type of an input. Nothing like templates but they can answer this old question like this:
#define echo_tpl(X) _Generic((X), int: echo_tpl_i, \
char *: echo_tpl_s)(X)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl("Hello world");
echo_tpl(42);
}
You still have to define the function implementations using separate names as you would in C99, but you can define a macro with the C++-ish name that inserts a _Generic expression at every point of use, in order to choose the right version for that call site, without making the function user think about the argument type.
It seemingly takes forever for C standards to be fully adopted and I have no idea which compilers implement this feature, but it will become widespread sooner if more people go forth and use it!
template <typename T>
void echo_tpl(const T& t) { std::cout << t; }
EDIT: I didn't spot the c tag. The above answer only works with C++.