I need help in function pointers.
I have two function pointer types:
typedef void (*draw_func1_t)(void* data, void* painter, double x, double y);
typedef void (*draw_func2_t)(void* data, MyPainter* painter, double x, double y);
The two types are almost the same, except the second parameter. Now I need to write a function that convert a draw_func1_t to draw_func2_t:
draw_func2_t convert_func_p(draw_func1_t func) { ... }
How can I write it? Can I just force a cast like
return (draw_func2_t)func;
because the two function prototypes are binary compatible?
If you cast a function pointer to a different type, then the behaviour on its calling is undefined. See Annex J.2 of the C standard:
The behaviour is undefined in the following circumstances: A pointer
is used to call a function whose type is not compatible with the
pointed-to type (6.3.2.3).
Compatibility is dealt with in 6.7.5.1, paragraph 2:
For two pointer types to be compatible, both shall be identically
qualified and both shall be pointers to compatible types.
A MyPainter* is not compatible with a void*. So your function pointer cast cannot be used to call the function.
Since use of:
draw_func1_t convert_func_p(draw_func2_t func)
{
return (draw_func1_t)func;
}
leads to undefined behavior, you might want to change your strategy.
Say you have:
void func2(void* data, MyPainter* painter, double x, double y)
{
printf("In func2, working with MyPainter\n");
}
and you would like to be able use that function indirectly through a function pointer.
One option is to use a wrapper function.
void func2_wrapper(void* data, void* painter, double x, double y)
{
// In this function, if you are sure that painter points to
// a valid MyPainter object, you can do this:
MyPainter* realPainter = (MyPainter*)painter;
// Then call the core function.
func2(data, realPainter, x, y);
}
Register func2_wrapper as a callback.
You can also make func2_wrapper simpler by removing the explicit cast to MyPainter*.
void func2_wrapper(void* data, void* painter, double x, double y)
{
func2(data, painter, x, y);
}
Theoretically, if you cast it to a different signature and call it, it is undefined behavior, as Bathsheba's answer cites, because the calling convention for calling different types of functions can be different.
However, practically, it will work on pretty much any real-world system, because pretty much all calling conventions treat different types of (non-function) pointers identically. And since that's the only difference (everything else, including the number of parameters and return type are the same), the calling conventions will almost certainly be the same. You can check the function-calling ABI for your specific system to make sure.
The following compiles without warnings (VC2008) and shows that the two function types are compatible. Unexpectedly, a void * is accepted where a MyPainter * is requied.
typedef struct {
int x;
int y;
} MyPainter;
typedef void (*draw_func1_t)(void* data, void* painter, double x, double y);
typedef void (*draw_func2_t)(void* data, MyPainter* painter, double x, double y);
void f1(void* data, void* painter, double x, double y);
void f2(void* data, MyPainter* painter, double x, double y);
void f1(void* data, void* painter, double x, double y)
{
f2(data,painter,x,y); // no compiler warning is unexpected
}
void f2(void* data, MyPainter* painter, double x, double y)
{
f1(data,painter,x,y); // no compiler warning is expected
}
void pTest(void)
{
MyPainter p = {0,0};
draw_func1_t pf1;
draw_func2_t pf2;
pf1= f1;
pf2= f1;
pf1= f2;
pf2= f2;
pf1(0,&p,0.0,0.0);
pf2(0,&p,0.0,0.0);
}
Related
In short, my question is: does the C standard allow for an arbitrary function pointer type similar to void * being an arbitrary data pointer type?
It is common to define call-back function types with a void * parameter to pass on an arbitrary data package whose format is known to the call-back function, but not to the caller.
For example:
typedef void (* EventFunctionType)(void *data);
void RegisterEventFunction(EventFunctionType function, void *data);
An "EventFunction" can then be registered with a data pointer which will be passed to the function when it is called.
Now suppose we want to pass a function pointer to the call-back. The function could have any prototype which would be known to the specific call-back function, just like the arbitrary data structure above.
A void * cannot hold a function pointer, so which type could be used?
Note: An obvious solution to this problem would be to wrap the function pointer in a data structure with the correct function pointer type, but the question is if the function pointer could be passed on directly in a generic form which the call-back could then cast to a pointer with the correct prototype?
There are no function pointer type that works the same as/similar to to void-pointer.
But function pointers has another characteristic that can be used. It's already referenced in the answer linked in this question:
In the C11 draft standard N1570, 6.3.2.3 §8:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again.
This mean that you can use any function pointer type as your "arbitrary function pointer type". It doesn't matter as long as you know how to get back to the real/original type (i.e. know the original type so that you can cast correctly).
For instance:
typedef void (*func_ptr_void)(void);
and then use func_ptr_void as your "arbitrary function pointer type".
But notice that unlike conversion between void* and other object pointer types, the conversion between function pointers will always require an explicit cast. The code example below shows this difference:
#include <stdio.h>
typedef void (*func_ptr_void)(void);
typedef int (*f_int)(int);
int bar(int n)
{
return n * n;
}
int test(func_ptr_void f, int y)
{
f_int fc = (f_int)f; // Explicit cast
return fc(y);
}
int foo(void* p)
{
int* pi = p; // Explicit cast not needed
return *pi;
}
int main(void)
{
int x = 42;
void* pv = &x; // Explicit cast not needed
printf("%d \n", foo(pv));
func_ptr_void fpv = (func_ptr_void)bar; // Explicit cast
printf("%d \n", test(fpv, 5));
return 0;
}
does the C standard allow for an arbitrary function pointer type similar to void * being an arbitrary data pointer type?
No. Two function pointers are only compatible if their return types and parameters (including qualifiers) match.
However, pointer conversions between any two function pointers by means of a cast are well-defined (6.3.2.3/8) as long as you don't invoke the function through the wrong pointer type. This means that you can use any function pointer type as a "generic function pointer" as long as you keep track of what function that pointer actually points at. Such as using an extra enum for that purpose.
Generally when using function pointers, we don't do that however, but instead define a common interface. For example like the callbacks to bsearch/qsort which use the form int (*)(const void*, const void*).
Here's an example of "keep track of type using enum", which is not something I particularly recommend but otherwise perfectly well-defined:
#include <stdio.h>
static int intfunc (int x)
{
printf("%d\n", x);
return x;
}
static double doublefunc (double x)
{
printf("%f\n", x);
return x;
}
typedef enum
{
INTFUNC,
DOUBLEFUNC
} functype_t;
typedef void generic_func_t (void);
typedef int int_func_t (int);
typedef int double_func_t (double);
typedef struct
{
generic_func_t* fptr;
functype_t type;
} func_t;
void func_call (const func_t* f)
{
switch(f->type)
{
case INTFUNC: ((int_func_t*)f->fptr ) (1); break;
case DOUBLEFUNC: ((double_func_t*)f->fptr) (1.0); break;
}
}
int main (void)
{
func_t f1 = { (generic_func_t*)intfunc, INTFUNC };
func_t f2 = { (generic_func_t*)doublefunc, DOUBLEFUNC };
func_call(&f1);
func_call(&f2);
}
That's "old school" C, but it is not recommended since it is clunky, brittle and not really type safe. In modern C programming we wouldn't write that kind of code however, but replace that whole mess with something like this:
#include <stdio.h>
static int intfunc (int x)
{
printf("%d\n", x);
return x;
}
static double doublefunc (double x)
{
printf("%f\n", x);
return x;
}
#define func_call(obj) \
_Generic((obj), \
int: intfunc, \
double: doublefunc) (obj) \
int main (void)
{
func_call(1);
func_call(1.0);
}
I wrote a function that receives a void * type argument and the plan that I can pass char* and int and in the receiving function I read whatever I expect.
It looks like:
void __declspec(dllexport) void* func(void *);
Next i tried to pass a double here:
double d = 3.14;
(*funcPtr)( (void *)d );
but got an error:
error: invalid cast from type 'double' to type 'void*'
Then I gone through method to pass double to void argument thread and tried this way:
double d = 3.14;
double *p_d = (double *)d;
(*funcPtr)( (void *)p_d );
But still the same luck:
error: invalid cast from type 'double' to type 'double*'
What am I missing and how to resolve my problem? I thought a solution would be to define several typedef of function pointers.
double d = 3.14;
double *p_d = &d;
You don't cast from a type to a pointer you need to reference it.
When you need to use the value in the pointer you dereference it like so.
double new_d = *p_d;
And inside a function that receives p_d as a void pointer, you'll have to cast the pointer back to a double pointer before use.
Like
void func(void *p_d)
{
double new_d = *(double*)p_d;
...
}
You have two general ways of doing this:
Get a pointer to either the double instance itself, or to a wrapper that holds it. Depending on how you call this thing, this may easily lead to an access violation if the value is held on the stack and your function ends before the called function uses the pointer.
double val;
fn(&val);
On a 64-bit system, if you're sure enough in your pointer-fu, you can store it as the pointer itself. Make sure you do the reverse in the called function, it won't be a pointer, it will be the double data itself.
double v;
fn((void *)(*(long long *)&v));
Similarly to what Blindy suggested it his option 2, I wanted to offer:
double d = 3.14;
void* p;
int id = sizeof d;
int ip = sizeof p;
//p = (void*)d;
memcpy(&p, &d, id);
If NoOb is dealing with a third-party library (judging by __declspec(dllexport)), he may not have a freedom to change interface.
Also, you should not be passing pointers to a library, as you don't know when is it safe to free it (and you can't delegate freeing to the library either).
A void* in C was used as universal storage for ages. If you can make sure that it has enough bits, and you know that the library is not going to derefernce it - just do it.
I have recently stumbled on this curious thought while handling a C code.
I have written a function which returns a double and takes in as argument the pointer to a function and a certain number of parameters, namely
double template_1(double (*)(double),...);
this function correctly identifies a certain property of a real function
double f(double );
represented as a pointer in template_1, in order to maketemplate_1 valid for every real function I might plug-in.
Now I had to write another function, let it be:
double derivative(double (*)(double),double);
double derivative(double (*f)(double),double x){
double epsilon = ...;
return ( f(x+epsilon)-f(x-epsilon) )/(2.0*epsilon);
}
again with f in the argument to make it work for every f.
My question is: since I would like to use derivative in template_1 without modifying it, is it possible to write a function which takes derivative and spits out something that has the form of double (*)(double ) ?
My idea was to define typedef double (*real_function)(double);
and then to define
real_function g(double (*derivative)(double (*)(double),double ) )
which I'd like it to spit out something like: double derivative_2(double x); so that I could define something like g(derivative) = double (*h)( double); directly in template_1 argument
unfortunately I don't have the faintest idea of how to make this work, or even if it can work.
There are a couple ways to do anonymous functions in C. As the comments said, they aren't portable. But depending on the use case you may find this useful: Anonymous functions using GCC statement expressions
A couple of people have seemed to have similar issues, not sure how portable they are but they may be resourceful:
https://github.com/graphitemaster/lambdapp
https://github.com/Leushenko/C99-Lambda
Basically, if there's a way to architect your program in a way that doesn't require anonymous functions, then do it that way. If you have no other option, then I would give one of these a shot.
Warning: I am a C++ developer with little C knowledge so everything that follows is likely unidiomatic C.
As KerrekSB said, you would need to carry some state with your function. This is not possible with raw functions but you can define a struct that carries the state and add a function that works with this struct. This obviously has the drawback of losing the nice function call syntax. I whipped up an example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef double (*raw_fptr)(double);
struct real_function;
typedef double (*evaluate_function)(struct real_function*, double);
struct real_function {
evaluate_function evaluate;
};
typedef struct real_function real_function;
double evaluate(real_function *f, double x) {
if(f) {
return f->evaluate(f, x);
}
return NAN;
}
struct raw_real_function {
real_function real_function_base;
raw_fptr raw_function;
};
typedef struct raw_real_function raw_real_function;
double evaluate_raw_real_function(real_function *f_base, double x) {
if(f_base) {
raw_real_function *f = (raw_real_function*)f_base;
return f->raw_function(x);
}
return NAN;
}
raw_real_function make_raw_real_function(raw_fptr function) {
raw_real_function result;
result.raw_function = function;
result.real_function_base.evaluate = evaluate_raw_real_function;
return result;
}
struct derive_real_function {
real_function real_function_base;
real_function *function_to_derive;
};
typedef struct derive_real_function derive_real_function;
double derive(real_function *f_base, double x) {
derive_real_function *f = (derive_real_function*)f_base;
double epsilon = 1e-3;
double upper = evaluate(f->function_to_derive, x+epsilon);
double lower = evaluate(f->function_to_derive, x-epsilon);
double result = (upper - lower)/(2.0*epsilon);
return result;
}
derive_real_function make_derivative(real_function * function_to_derive) {
derive_real_function result;
result.real_function_base.evaluate = derive;
result.function_to_derive = function_to_derive;
return result;
}
double x_cubed(double x) {
return x * x * x;
}
int main(int argc, char **argv) {
raw_real_function x_cubed_wrapped = make_raw_real_function(x_cubed);
derive_real_function derived = make_derivative(&x_cubed_wrapped.real_function_base);
derive_real_function derived_twice = make_derivative(&derived.real_function_base);
double x = atof(argv[1]);
double derivative = evaluate(&derived.real_function_base, x);
double second_derivative = evaluate(&derived_twice.real_function_base, x);
printf("derivative of x^3 at %f = %f\n", x, derivative);
printf("second derivative of x^3 at %f = %f\n", x, second_derivative);
return 0;
}
See (a slight variaton, due to input limitations) running here.
How does it work? I faked some inheritance with the structs real_function, raw_real_function and derive_real_function to generate virtual function calls. The struct real_function serves as the container of a virtual function table consisting of only the entry evaluate. This function pointer points to the "derived" structs' relevant evaluate function:
raw_real_function instances point to evaluate_raw_real_function (as initialized in make_raw_real_function. derive_real_function instances point evaluate to derive (as initialized in make_derivative).
When calling evaluate on the real_function_base member, it will call the associated evaluation function, which casts the real_function* to it's associated struct pointer and does what is needed with that information.
Since everything is just a real_function*, we can chain them at will but need to convert "normal" functions into the real_function format, that's what make_raw_real_function does.
If you have a function my_fancy_function:
double my_fancy_function (double x) { return sin(x) + cos(x); }
Then, you can use a helper macro that creates the derived function for you.
#define DEFINE_DERIVATIVE_OF(FUNC) \
double derivative_of_ ## FUNC (double x) { \
return derivative(FUNC, x); \
}
DEFINE_DERIVATIVE_OF(my_fancy_function)
You then pass this newly defined function to your template.
template_1(derivative_of_my_fancy_function, x, y, z);
I have been reading about having functions with functions as parameters, and particulary in C, they use function pointers. Let's suppose I want to implement the newton raphson method (in a simple way) for computing zeros in non linear equations.
double derivative(double f(double), double x)
{
double h = 1e-9;
return (f(x + h) - f(x)) / h;
}
double newton_raphson(double f(double), double x0, double tol)
{
double xk, diff;
do
{
xk = x0 - f(x0) / derivative(f, x0);
diff = fabs(xk - x0);
x0 = xk;
} while (diff >= tol);
return xk;
}
So, to compute an approximation for derivative I need a function that returns a double and takes a double as an argument. Same for computing a root of the function, given the other parameters. My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...
The parameter f is a pointer-to-function in both derivative and newton_raphson.
double derivative(double f(double), double x) { ... }
is exactly equivalent to
double derivative(double (*f)(double), double x) { ... }
Only, the former looks nicer - usually when you can omit parentheses, you should probably do so. After all both of them are equivalent to
double ((((derivative)))(double (((*(f))))(double ((trouble))), double ((x)))) { ... }
That I hope will only ever be used in IOCCC.
However, if you're declaring, defining a variable (not a function parameter), you need to use
double (*f)(double);
as
double f(double);
is just a function declaration.
6.7.6.3 Function declarators (including prototypes) of C11 draft n1570 says:
A declaration of a parameter as ‘‘function returning
type
’’ shall be adjusted to ‘‘pointer to
function returning
type
’’, as in 6.3.2.1.
And
6.9.1 Function definitions further says that
[...] the type of each parameter is adjusted as described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object
type.
additionally it has the following example:
EXAMPLE 2
To pass one function to another, one might say
int f(void);
/* ... */
g(f);
Then the definition of g might read
void g(int (*funcp)(void))
{
/* ... *
(*funcp)(); /* or funcp(); ... */
}
or, equivalently,
void g(int func(void))
{
/* ... */
func(); /* or (*func)(); ... */
}
Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function. A function’s name holds the address of function.
My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...
The answer is that both forms will be treated as same by compiler.
But for readibility of your code, go with the kind of declaration that your example code has, i.e.,
double derivative(double f(double), double x) { ... }
Even in C, the function definitions given below will be interpreted as same-
void foo(int a[]) // or int a[10]
{
...
}
void foo(int *a)
{
...
}
I'm 99% convinced that this is legitimate after reviewing the C standard and several comp.lang.c posts, but am hoping that someone can provide the precise language in the standard that allows (or forbids) this case:
#include <stdio.h>
double id (double x) { return x; }
double add2 (double x, double y) { return x + y; }
double add3 (double x, double y, double z) { return x + y + z; }
typedef double (*fp) ();
static fp funcs[] = { id, add2, add3 };
int main (void)
{
printf("id(5.3) = %f\n", funcs[0](5.3));
printf("add2(5.3, 6.1) = %f\n", funcs[1](5.3, 6.1));
printf("add3(5.3, 6.1, 7.2) = %f\n", funcs[2](5.3, 6.1, 7.2));
return 0;
}
The provided example gave the expected results for me under MinGW gcc 4.4.0 using -Wall -pedantic -ansi.
Considerations:
I'm aware that calls to functions with unspecified parameters implicitly promote integral arguments according to the integral promotion rules and float arguments to double. Does this behavior change in any way when calling through a function pointer to a function of unspecified parameters? (I don't see why it would.)
I came across several posts implying that calls to functions with ... specifiers (e.g. double uhoh (double x, ...)) are not permitted through function pointers to functions of unspecified parameters. This makes sense from an implementation perspective, but I haven't been able to pin down the clause in the standard which forbids this.
First I can suggest that the standard function call syntax:
void foo(int);
foo(3);
is defined in terms of foo decaying to a function pointer, then being invoked; therefore I don't see why there would be any difference between your situation and a "standard" function call.
Second, n1256 6.5.2.2 details function call semantics, and it seems pretty well-defined for a function pointer with no prototype provided the number and type of arguments matches the number and type of parameters.
An empty parameter list is incompatible with a variadic parameter list according to n1256 6.7.5.3p15:
If one type has a parameter type list
and the other type is specified by a
function declarator that is not part
of a function definition and that
contains an empty identifier list, the
parameter list shall not have an
ellipsis terminator and the type of
each parameter shall be compatible
with the type that results from the
application of the default argument
promotions.
This means it is a constraint violation (6.5.16.1p1) to assign a variadic function pointer to a pointer-to-function with no prototype, since you are assigning pointers to incompatible types.
I would guess that casting a variadic function pointer to a non-prototyped function pointer is also UB and possibly a CV; but I haven't checked.
You are correct that this program has entirely well-defined behavior as long as the arguments when you make the call are of the number and types matching those in the definition of the function that gets called. See 6.5.2.2 paragraph 6. My related question may also be of interest:
Is this dubious use of a non-prototype function declaration valid?
The code is well-defined as long as all parameter types promote to themselves and all supplied argument are of correct type.
If you want to get back some measure of type-safety, you could use explicit casts or unions, eg
#include <stdio.h>
static double id(double x) { return x; }
static double add2(double x, double y) { return x + y; }
static double add3(double x, double y, double z) { return x + y + z; }
union func
{
double (*as_unary)(double x);
double (*as_binary)(double x, double y);
double (*as_ternary)(double x, double y, double z);
};
static const union func funcs[] = {
{ .as_unary = id },
{ .as_binary = add2 },
{ .as_ternary = add3 }
};
int main(void)
{
printf("id(5.3) = %f\n", funcs[0].as_unary(5.3));
printf("add2(5.3, 6.1) = %f\n", funcs[1].as_binary(5.3, 6.1));
printf("add3(5.3, 6.1, 7.2) = %f\n", funcs[2].as_ternary(5.3, 6.1, 7.2));
return 0;
}