Mostly for fun, I've decided to write my own minimal test framework for my C code. I use a basic struct for the test information, create an array of test structs and then iterate over them to run all the tests. This amounts to a very small amount of work for a fairly elegant (imho) solution.
However, the one thing that is a little annoying is that I cannot figure out how to define functions as function pointers instead of defining the function and then creating a function pointer later.
I have the following (which works just fine):
typedef int (* test_p) (void);
struct test {
char * desc;
test_p func;
};
int
example_test (void) {
puts("This is a test");
return 0;
}
void
run_test (char * test_name, test_p test) {
printf("Testing %s\t\t\t[ PEND ]\r", test_name);
char * test_result = (test() ? "FAIL" : "PASS");
printf("Testing %s\t\t\t[ %s ]\n", test_name, test_result);
}
int
main (void) {
struct test test_list [] = {
{ "example test", (test_p )example_test }
};
for ( int i = 0; i < 1; i ++ ) {
run_test(test_list[i].desc, test_list[i].func);
}
return 0;
}
However, I am hoping I can remove the need for the casting in the struct and instead define the function as being a function pointer from the beginning. The following is an example of how I would like this to work (assuming many of the same things as above):
test_p
example_test = {
puts("This is a test");
return 0;
}
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test. Is this (or something like it) possible? If not, is there a reason why not (If that reason is simply "because it wasn't added to the language", that's fine)?
A function pointer is one kind of thing and a function is another kind of thing so you can't really make the latter be the former. But if you use a function name where a function pointer is expected, that produces a pointer to the function, so you can just remove the unnecessary cast, as WhozCraig said in the first comment above. You write
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test.
You can do that, with example_test defined just as it is in your current code ... did you try that?
You can also forward declare a function, like so:
typedef int test_func(void); // note no indirection
typedef test_func* test_p;
test_func example_test;
It would be nice if you could use that sort of syntax when you define the function, as in your attempted syntax, but there's simply no way to do that in C ... you have to explicitly provide the return type and parameter list.
Another detail is that, when you invoke the function pointed to by a function pointer, you don't have to dereference it ... that's why you were able to write
test()
instead of
(*test)()
although the latter also works. (In fact, because the deference is stripped, (********test)() also works ... but only do that if you're trying to win an obfuscation contest.)
What you are describing is a kind of meta-programming. Rather than writing code to explicitly solve the problem, you are concerned with a kind of syntactic structure that will allow you to define a whole raft of test functions without unnecessary cruft.
In Lisp you would use macros. In C++ you might use templates and/or lambdas. In C you use macros.
So you need to write a macro that:
takes a name and descriptive text as arguments
defines a static variable of type function (created from that name using token pasting)
defines a function (using a name created by token pasting)
[edit] At this point you have achieved the goal: you have created the function and given it a name that is (only) a function pointer, and you can use that name in your struct without a cast. I would suggest one additional step, the macro also:
adds the variable/function and descriptive text to a list of functions to be tested.
Then your boilerplate loop iterates over the structure calling each function and reporting the results using the descriptive text. Problem solved.
Some people don't like macros, but they are ideally suited to this situation, and there is no other way to do it in C. I did something just like this before making the move to C++.
Related
In C you can declare a variable that points to an array like this:
int int_arr[4] = {1,2,3,4};
int (*ptr_to_arr)[4] = &int_arr;
Although practically it is the same as just declaring a pointer to int:
int *ptr_to_arr2 = int_arr;
But syntactically it is something different.
Now, how would a function look like, that returns such a pointer to an array (of int e.g.) ?
A declaration of int is int foo;.
A declaration of an array of 4 int is int foo[4];.
A declaration of a pointer to an array of 4 int is int (*foo)[4];.
A declaration of a function returning a pointer to an array of 4 int is int (*foo())[4];. The () may be filled in with parameter declarations.
As already mentioned, the correct syntax is int (*foo(void))[4]; And as you can tell, it is very hard to read.
Questionable solutions:
Use the syntax as C would have you write it. This is in my opinion something you should avoid, since it's incredibly hard to read, to the point where it is completely useless. This should simply be outlawed in your coding standard, just like any sensible coding standard enforces function pointers to be used with a typedef.
Oh so we just typedef this just like when using function pointers? One might get tempted to hide all this goo behind a typedef indeed, but that's problematic as well. And this is since both arrays and pointers are fundamental "building blocks" in C, with a specific syntax that the programmer expects to see whenever dealing with them. And the absensce of that syntax suggests an object that can be addressed, "lvalue accessed" and copied like any other variable. Hiding them behind typedef might in the end create even more confusion than the original syntax.
Take this example:
typedef int(*arr)[4];
...
arr a = create(); // calls malloc etc
...
// somewhere later, lets make a hard copy! (or so we thought)
arr b = a;
...
cleanup(a);
...
print(b); // mysterious crash here
So this "hide behind typedef" system heavily relies on us naming types somethingptr to indicate that it is a pointer. Or lets say... LPWORD... and there it is, "Hungarian notation", the heavily criticized type system of the Windows API.
A slightly more sensible work-around is to return the array through one of the parameters. This isn't exactly pretty either, but at least somewhat easier to read since the strange syntax is centralized to one parameter:
void foo (int(**result)[4])
{
...
*result = &arr;
}
That is: a pointer to a pointer-to-array of int[4].
If one is prepared to throw type safety out the window, then of course void* foo (void) solves all of these problems... but creates new ones. Very easy to read, but now the problem is type safety and uncertainty regarding what the function actually returns. Not good either.
So what to do then, if these versions are all problematic? There are a few perfectly sensible approaches.
Good solutions:
Leave allocation to the caller. This is by far the best method, if you have the option. Your function would become void foo (int arr[4]); which is readable and type safe both.
Old school C. Just return a pointer to the first item in the array and pass the size along separately. This may or may not be acceptable from case to case.
Wrap it in a struct. For example this could be a sensible implementation of some generic array type:
typedef struct
{
size_t size;
int arr[];
} array_t;
array_t* alloc (size_t items)
{
array_t* result = malloc(sizeof *result + sizeof(int[items]));
return result;
}
The typedef keyword can make things a lot clearer/simpler in this case:
int int_arr[4] = { 1,2,3,4 };
typedef int(*arrptr)[4]; // Define a pointer to an array of 4 ints ...
arrptr func(void) // ... and use that for the function return type
{
return &int_arr;
}
Note: As pointed out in the comments and in Lundin's excellent answer, using a typedef to hide/bury a pointer is a practice that is frowned-upon by (most of) the professional C programming community – and for very good reasons. There is a good discussion about it here.
However, although, in your case, you aren't defining an actual function pointer (which is an exception to the 'rule' that most programmers will accept), you are defining a complicated (i.e. difficult to read) function return type. The discussion at the end of the linked post delves into the "too complicated" issue, which is what I would use to justify use of a typedef in a case like yours. But, if you should choose this road, then do so with caution.
I'd like to know how to solve the wrapper problem from the
Stroustrup paper but in C. I'm trying to find an efficient way to call
// prefix
GenericFunctionCallThatCouldHaveAnyNumberOfArgs();
// suffix
I've thought about creating a proxy function that takes an input a function pointer but the functions I want to wrap do not all have the same function signature.
My current solution is to create a Macro:
#define CALL(func) prefix; func; suffix;
CALL(myfunction(a, 'b', 1))
It works but it makes the code harder to understand especially when the prefix and suffix are complicated. Also the prefix and suffix are not necessarily calls to functions, they can be enclosures too. Is there a design pattern in C that does this efficiently (in terms of lines of code) while still maintaining readability.
I've thought about creating a proxy function that takes an input a function pointer but the functions I want to wrap do not all have the same function signature.
This can be solved by adding another layer of indirection. It won't make the code any shorter, though.
Let's say we want to call two functions, foo() (passing no arguments) and bar(42, "hello") (two arguments of different types) with the same prefix/suffix code.
We can do it like this:
void call_decorated(void (*f)(void *), void *p) {
printf("prefix code\n");
f(p);
printf("suffix code\n");
}
This lets us call any function that takes a single void * argument. To use this with foo and bar, we have to write adapter functions:
void wrap_foo(void *p) {
foo();
}
struct bar_args {
int n;
const char *s;
};
void wrap_bar(void *p) {
struct bar_args *args = p;
bar(args->n, args->s);
}
Now we can call call_decorated like this:
call_decorated(wrap_foo, NULL);
struct bar_args args = { 42, "hello" };
call_decorated(wrap_bar, &args);
This gets very tedious, but there is only one instance of the prefix/suffix code in the source.
For function calls of return type void you could use the comma operator, which - with some restrictions - allows to specify several expressions that are evaluated one after the other, including a function call.
For example, you could write
#define prefix printf("something in prefix\n")
#define suffix printf("something as suffix\n")
void someFunction(int x) {
printf("some function, parameter value %d\n", x);
}
#define CALL(func) (prefix,func,suffix)
int main() {
CALL(someFunction(10));
}
Output:
something in prefix
some function, parameter value 10
something as suffix
There are several restrictions on what can be an expression used within a comma operator. For example, you cannot define a variable in the course of such an expression. However, there are some strategies to overcome this, e.g. by introducing global variables or by calling functions (which may define local variables, of course).
The reason for return type void is that you want to call your function "in the middle", i.e. not as the last expression in the comma operator, but the result of the comma operator per is always the value to which the last expression evaluates. Note further that with the #define CALL(func)- approach any change in the prefix or in the suffix requires recompilation of your program. But I think you are aware of this anyway.
Hope it helps.
I want to do some object-oriented style programming in C using polymorphism, where my interface class contains a pointer to a table of functions. Example something like:
/* Implement polymorphism in C, Linux kernel-style */
struct statement {
const struct statement_ops *ops;
struct list_head list; /* when on master input list */
void *private; /* pointer to type-specific data */
};
struct statement_ops {
int (*analyse)(void *private, int pc);
int (*get_binary_size)(void *private);
};
void user(void)
{
struct statement *s = make_a_statement();
if (s->ops->analyse(s->private, foo))
blah blah;
}
I'd like to be able to write something without explicitly passing s->private into every "method". Any ideas? Some macro tricks maybe?
If this is part of the public interface, you can add accessor functions. A hidden benefit is that you can do sanity checks and other work in the accessor. (Note I called the "this" pointer "o", as in "object". I prefer it that way for consistency.)
int statement_analyse (struct statement *o, int pc)
{
assert(pc >= 0);
int ret = o->ops->analyse(o->private, pc);
assert(ret >= 0);
return ret;
}
You can now call this without the explicit passing of "private".
void user(void)
{
struct statement *s = make_a_statement();
if (statement_analyse(s, foo))
blah blah;
}
While it may seem that this provides no benefit, because you still have to implement the accessors, assuming that you want a well defined and robust interface, the accessor functions are the only sane place to put the assertions and the interface documentation. In fact, if you write good assertions, the assertions themselves help document the interface. And once you add sanity checks in the accessors, you don't have to add them in the actual methods they call.
Of course, this approach only makes sense when the function called via the function pointer will be something provided by the user, or in some other way can be different things. If there's a single analyse() method that will always do the same thing, you can simply implement a statement_analyse() that directly does what it needs to do.
Small note: when doing OOP, I prefer to typedef the structs and give them CamelCase names. I use this convention as a way of telling that the struct is opaque and should only be accessed via its public interface. It also looks nicer, though that is subjective. I also prefer having the user allocate the memory for the struct itself, as opposed to the constructor malloc'ing it. That avoids having to handle malloc failure, and makes the program a little bit more efficient.
typedef struct {
...
} Statement;
void Statement_Init (Statement *o);
int Statement_Analyse (Statement *o, int pc);
Unfortunately, writing your methods to allow the passing of a self or this object is the only way to achieve this in C.
You can use macro tricks to hide part of it, but at that point it's not really C any more.
As the other answers say, there is no way to do this without calling the function with the appropriate pointer, but (as Williham Totland suggests) you could use macros to streamline the calls (requires a compiler with variadic macro support):
// macro_call.c
#define C_ARGS(stmnt, func, ...) (stmnt)->ops->func((stmnt)->private, ...)
#define C_NOARGS(stmnt, func) (stmnt)->ops->func((stmnt)->private)
C_ARGS(s, analyse, 1);
C_ARGS(s, lots_of_args, 1, 2, 3, 4);
C_NOARGS(s, no_args);
(The C is for "call".)
Doing the preprocessing on that (via gcc -E macro_call.c) gives:
(s)->ops->analyse((s)->private, 1);
(s)->ops->lots_of_args((s)->private, 1, 2, 3, 4);
(s)->ops->no_args((s)->private);
This is similar to the accessor function version: the macro version is slightly more flexible in some ways, but it is also less safe and could lead to subtle errors and mistakes.
There are two macros because passing no extra arguments to C_ARGS would result in s->ops->func(s->private, ), I think it is possible to fix this, but it is awkward and would require significantly more code (empty __VA_ARGS__ are notoriously hard to deal with).
This question is about the appropriateness of using void pointers in a particular implementation.
I have a relatively simple program that consists of an infinite loop. On each loop, the program iterates over a fixed range of constant values and calls a function on each value. The particular function which is called can be one of three available and is specified at run time by an argument. Before the infinite loop starts, there is a condition block which sets a functional pointer to a function based on the supplied argument. This way the condition logic only has to be run once and not on every iteration in every loop.
This I have implemented and it works well, but I want to keep state between each call to the function. My proposal is to store state in a struct and pass that struct when calling the function on each of the values. The problem is that each function requires a different struct to store a different set of values of its state and the prototype of all three functions must be compatible (for the function pointer). I intend to solve this by using a void pointer in the prototypes of the three functions, thus maintaining compatible prototypes but allowing me to pass a different struct to each function.
The question is; is my proposal an appropriate use of void pointers or is it introducing too much runtime dynamism and I should therefore rethink my approach?
Note: It is not possible to use static variables in each of the three functions as the structs also need to be available in the infinite loop as there is also some processing to be done before and after the range of values is iterated.
As long as you are careful to keep your calls type-correct, this is a fairly C-idiomatic way to accomplish what you describe.
You could gain some measure of type safety by using a union:
typedef struct {
int a;
char *b;
} s1;
typedef struct {
double d;
int *e;
} s2;
typedef union {
s1 s1;
s2 s2;
} ocd;
typedef int (*daemon_function)(ocd *);
Then all your functions could be of type daemon_function but take different arguments through ocd.s1 or ocd2.s2. I'd tend to call all that a bunch of pointless busy-work though. A simple void* would work just as well.
You could also include a magic number at the front of your structures and then the functions could check type safety by looking at the magic number and seeing if it was the right one:
#define MAGIC 0x4d475600L
typedef struct {
long magic;
/* ... */
} whatever;
And then:
int f(void *p) {
whatever *w = (whatever *)p;
if(w->magic != MAGIC) {
/* complain and go boom! */
}
/* ... */
}
I did the magic number trick all the time back in my Motif programming days, you pass around a lot of void* pointers in Motif/Xt/X11 development.
Void pointers are a method to tell the c typing system that you want it to stop doing its job and trust you to not mess up. It is an appropriate use of a void *, the only issue is that you have lost access to any type checking that your compiler performs. You can potentially create some very bizarre and hard to diagnose bugs. If you are sure that you know what you are doing (you sound like you do) and if you have checked every single line of your code several times and are sure that there are no logical errors in it, then you should be fine.
void * is quite idiomatic in C. Personally I use it prevalently, but whenever I do it, I tend to used tagged structures for safety, i.e. I put a unique type ID at the beginning of each structure to identify it.
Generally it is OK.
I really prefer using the void * contexts but it looks like you want to avoid it.
Since you already have some code that parses the argument and choose the function, you can just select the function in a switch and call it explicitly for each iteration.
Let's say I'm creating a chess program. I have a function
void foreachMove( void (*action)(chess_move*), chess_game* game);
which will call the function pointer action on each valid move. This is all well and good, but what if I need to pass more parameters to the action function? For example:
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
foreachMove(moveHandler, game);
}
void moveHandler(chess_move* move){
//uh oh, now I need the variables "game" and "depth" from the above function
}
Redefining the function pointer is not the optimal solution. The foreachMove function is versatile and many different places in the code reference it. It doesn't make sense for each one of those references to have to update their function to include parameters that they don't need.
How can I pass extra parameters to a function that I'm calling through a pointer?
Ah, if only C supported closures...
Antonio is right; if you need to pass extra parameters, you'll need to redefine your function pointer to accept the additional arguments. If you don't know exactly what parameters you'll need, then you have at least three choices:
Have the last argument in your prototype be a void*. This gives you flexibility of passing in anything else that you need, but it definitely isn't type-safe.
Use variadic parameters (...). Given my lack of experience with variadic parameters in C, I'm not sure if you can use this with a function pointer, but this gives even more flexibility than the first solution, albeit still with the lack of type safety.
Upgrade to C++ and use function objects.
You'd probably need to redefine the function pointer to take additional arguments.
void foreachMove( void (*action)(chess_move*, int), chess_game* game )
If you're willing to use some C++, you can use a "function object":
struct MoveHandler {
chess_game *game;
int depth;
MoveHandler(chess_game *g, int d): game(g), depth(d) {}
void operator () (chess_move*) {
// now you can use the game and the depth
}
};
and turn your foreachMove into a template:
template <typename T>
void foreachMove(T action, chess_game* game);
and you can call it like this:
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
foreachMove(MoveHandler(game, depth), game);
}
but it won't disrupt your other uses of MoveHandler.
If I'm reading this right, what I'd suggest is to make your function take a pointer to a struct as an argument. Then, your struct can have "game" and "depth" when it needs them, and just leave them set to 0 or Null when you don't need them.
What is going on in that function? Do you have a conditional that says,
if (depth > -1) //some default
{
//do something
}
Does the function always REQUIRE "game" and "depth"? Then, they should always be arguments, and that can go into your prototypes.
Are you indicating that the function only sometimes requires "game" and "depth"? Well, maybe make two functions and use each one when you need to.
But, having a structure as the argument is probably the easiest thing.
I'd suggest using an array of void*, with the last entry always void.
say you need 3 parameters you could do this:
void MoveHandler (void** DataArray)
{
// data1 is always chess_move
chess_move data1 = DataArray[0]? (*(chess_move*)DataArray[0]) : NULL;
// data2 is always float
float data1 = DataArray[1]? (*(float*)DataArray[1]) : NULL;
// data3 is always char
char data1 = DataArray[2]? (*(char*)DataArray[2]) : NULL;
//etc
}
void foreachMove( void (*action)(void**), chess_game* game);
and then
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
void* data[4];
data[0] = &chess_move;
float f1;
char c1;
data[1] = &f1;
data[2] = &c1;
data[3] = NULL;
foreachMove(moveHandler, game);
}
If all the parameters are the same type then you can avoid the void* array and just send a NULL-terminated array of whatever type you need.
+1 to Antonio. You need to change your function pointer declaration to accept additional parameters.
Also, please don't start passing around void pointers or (especially) arrays of void pointers. That's just asking for trouble. If you start passing void pointers, you're going to also have to pass some kind of message to indicate what the pointer type is (or types are). This technique is rarely appropriate.
If your parameters are always the same, just add them to your function pointer arguments (or possibly pack them into a struct and use that as the argument if there are a lot of parameters). If your parameters change, then consider using multiple function pointers for the multiple call scenarios instead of passing void pointers.
If your parameters change, I would change the function pointer declaration to use the "..." technique to set up a variable number of arguments. It could save you in readability and also having to make a change for each parameter you want to pass to the function. It is definately a lot safer than passing void around.
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html
Just an FYI, about the example code in the link: some places they have “n args” and others it is “n_args” with the underscore. They should all have the underscore. I thought the syntax looked a little funny until I realized they had dropped the underscore in some places.
Use a typedef for the function pointer. See my answer for this question
Another option would be to modify the chess_move structure instead of the function prototype. The structure is presumably defined in only one place already. Add the members to the structure, and fill the structure with appropriate data before any call which uses it.