How to wrap function with prefix and suffix in C - c

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.

Related

Resource Acquisition Is Initialization in C lang

The question is: Could you please help me understand better the RAII macro in C language(not c++) using only the resources i supply at the bottom of this question? I am trying to analyse it in my mind so as to understand what it says and how it makes sense(it does not make sense in my mind). The syntax is hard. The focus of the question is: i have trouble reading and understanding the weird syntax and its implementation in C language.
For instance i can easily read, understand and analyse(it makes sense to me) the following swap macro:
#define myswap(type,A,B) {type _z; _z = (A); (A) = (B); (B) = _z;}
(the following passage is lifted from the book: Understanding C pointers)
In C language the GNU compiler provides a nonstandard extension to
support RAII.
The GNU extension uses a macro called RAII_VARIABLE. It declares a
variable and associates with the variable:
A type
A function to execute when the variable is created
A function to execute when the variable goes out of scope
The macro is shown below:
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Example:
void raiiExample() {
RAII_VARIABLE(char*, name, (char*)malloc(32), free);
strcpy(name,"RAII Example");
printf("%s\n",name);
}
int main(void){
raiiExample();
}
When this function is executed, the string “RAII_Example” will be displayed. Similar results can be achieved without using the GNU extension.
Of course you can achieve anything without using RAII. RAII use case it to not have to think about releasing ressources explicitly. A pattern like:
void f() {
char *v = malloc(...);
// use v
free v;
}
need you to take care about releasing memory, if not you would have a memory leak. As it is not always easy to release ressources correctly, RAII provides you a way automatize the freeing:
void f() {
RAII_VARIABLE(char*, v, malloc(...), free);
// use v
}
What is interesting is that ressource will be released whatever the path of execution will be. So if your code is a kind of spaghetti code, full of complex conditions and tests, etc, RAII lets you free your mind about releasing...
Ok, let's look at the parts of the macro line by line
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
This first line is, of course, the macro name plus its argument list. Nothing unexpected here, we seem to pass a type, a token name, some expression to init a variable, and some destructor that will hopefully get called in the end. So far, so easy.
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
The second line declares a function. It takes the provided token varname and prepends it with the prefix _dtor_ (the ## operator instructs the preprocessor to fuse the two tokens together into a single token). This function takes a pointer to vartype as an argument, and calls the provided destructor with that argument.
This syntax may be unexpected here (like the use of the ## operator, or the fact that it relies on the ability to declare nested functions), but it's no real magic yet. The magic appears on the third line:
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Here the variable is declared, without the __attribute__() this looks pretty straight-forward: vartype varname = (initvar). The magic is the __attribute__((cleanup(_dtor_ ## varname))) directive. It instructs the compiler to ensure that the provided function is called when the variable falls out of scope.
The __attribute__() syntax is is a language extension provided by the compiler, so you are deep into implementation defined behavior here. You cannot rely on other compilers providing the same __attribute__((cleanup())). Many may provide it, but none has to. Some older compilers may not even know the __attribute__() syntax at all, in which case the standard procedure is to #define __attribute__() empty, stripping all __attribute__() declarations from the code. You don't want that to happen with RAII variables. So, if you rely on an __attribute__(), know that you've lost the ability to compile with any standard conforming compiler.
The syntax is little bit tricky, because __attribute__ ((cleanup)) expects to pass a function that takes pointer to variable. From GCC documentation (emphasis mine):
The function must take one parameter, a pointer to a type compatible
with the variable. The return value of the function (if any) is
ignored.
Consider following incorrect example:
char *name __attribute__((cleanup(free))) = malloc(32);
It would be much simpler to implement it like that, however in this case free function implicitely takes pointer to name, where its type is char **. You need some way to force passing the proper object, which is the very idea of the RAII_VARIABLE function-like macro.
The simplified and non-generic incarnation of the RAII_VARIABLE would be to define function, say raii_free:
#include <stdlib.h>
void raii_free(char **var) { free(*var); }
int main(void)
{
char *name __attribute__((cleanup(raii_free))) = malloc(32);
return 0;
}

Defining a function as a function pointer

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++.

Can you pass a function with a variable amount of arguments as an argument to another function in C?

Related to [question]: How do you pass a function as a parameter in C?
Is it possible in C to pass a function that has a variable number of arguments to another function? If so, could someone point me to some documentation or fill me in? Thanks.
You can't pass a function (of any sort) as a parameter, but you can pass a pointer to a function (again, of pretty much any sort). It's usually easiest to use a typedef:
typedef int (*fptr)(char const *, ...); // e.g., match with `printf`
int apply(fptr f, char const *a, int b) {
return f(a, b);
}
You can make a function pointer, e.g.:
typedef int (*vafunc)(const char *, ...); // like printf
However, you cannot really forward the arguments, i.e. the following doesn't exist in standard C:
void call_other(vafunc f, const char * fmt, ...)
{
// want to say:
// f(fmt, ...); // How to write this???
}
GCC offers such anonymous argument forwarding as an extension, but it's not possible in standard C. You're typically expected to match each variadic function with a v... counterpart that takes a va_list argument, precisely for this purpose. (Calling f with a fixed number of arguments is possible, of course: f("abc", 1, 2, 3);)
http://www.lemoda.net/c/function-pointer-ellipsis/index.html seems to be what you seek.
You can pass a varargs function the same way as you would another function.
Here's a short test program that demonstrates passing a varargs function as a parameter:
int bar(int x, ...) {
/* In a real program, you would actually use the arguments beyond x */
return x;
}
int foo(int (*baz)(int, ...)) {
return bar(10, "ABC");
}
int main(void) {
printf("%d\n", foo(bar));
return 0;
}
It prints 10, as you might expect.
N.B. You can't actually pass a function as an argument to another function in C - instead, you can pass a function pointer, which points to the actual function as loaded from the executable. This is weaker than the first-class status of functions in functional programming languages, or even than the status of a delegate in some object-oriented languages like C#. For instance, you can't create a function on the fly in C.
Sure. They're called "variadic functions".
1) Just use an "ellipses" ("...") as the last argument in your function prototype
2) In order for the called function to "know" how many arguments were passed to it, use the macros "va_start" and friends in "stdargs":
3) 1) and 2) above are simply to have a function that has a variable #/arguments. You can also have a function pointer with a variable #/arguments. Do the same thing - just include the ellipses ("...") in your function prototype, and use "stdargs" in your function implementation.

How to set a default value when no extra arguments are present using va_list in C

I've had problem when trying write a function which has a default value when no extra arguments are given. I've tried detecting if the only argument given is equal to NULL (as suggested in other answers) but it doesn't seem to be working for me.
The actual implementation of this function takes a struct and adds it to a linked list given in the second argument. If no second argument is given, I want it to add it to a default global linked list which has been previously defined.
Below is a simpler version using int type arguments, but the principle of what I want to do is the same:
/* appropriate headers... */
void test(int a, ... ) {
int b;
va_list args;
va_start(args,a);
b = va_arg(args,int);
if (b == NULL) { // check if no argument is given and set default value
b = 0;
} // if b != NULL then it should be set to the value of the argument
va_end(args);
printf("%d %d\n",a,b);
}
int main() {
test(1);
test(1,1);
return 0;
}
However, this gives the output:
1 *random memory address*
1 1
The output I want should have the first line as
1 0
If I can't use this method then does anyone have any ideas how I can achieve what I want? Thanks in advance.
There is no way to do what you want with just va_list.
You can use macros and __VA_ARGS__ to force a certain argument to show up last in your argument list as a "terminator." i.e.:
#define TEST(a, ...) Test(a, __VA_ARGS__, 0)
Note that I'm using Visual C++. Other compilers might implement __VA_ARGS__ slightly differently so you may need to tweak the implementation.
Your function accepting variable arguments has to be able to tell somehow when it has reached the end of the variable arguments. This can be by parsing information from the fixed arguments (e.g. an argument which tells you how many variable arguments were passed, or a format string which tells you what arguments are supposed to follow), or it can be by an explicit sentinel value, such as a null pointer, at the end of the variable arguments.
You seem to be wanting a major miracle; I'm sorry, only minor miracles are available.
You can design your interfaces like this:
int test1(int x, struct list *list) { ...code to handle adding x to arbitrary list... }
int test0(int x) { return test1(x, &global_struct); }
You then call test0() when you want to use the default list, and test1() when you want specify a different list.
Note that test0() is so simple that it is a good candidate for C99 inline function definition.
If you were using C++ you could provide a function with a default argument or an overloaded function (two argument lists and implementations, as above, but the same name). Of course, even more than in C, the use of global variables is deprecated in C++.
A function has to have some way to know how many arguments it has been given. Your function has no way, so it can't work. You could create two functions. You could have a separate "number of arguments" parameter. You could include some other parameter that indirectly tells it how many parameters it has (like printf uses). But you have to do it somehow.

Passing more parameters in C function pointers

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.

Resources