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)
{
...
}
Related
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 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);
}
in the code below .
i have defined function prototype with no argument
in definition as well as in function call i have used one parameter.
i would like to know why i am not getting any error ?
# include <stdio.h>
float circle(); /* no parameter*/
int main()
{
float area;
int radius =2;
area=circle(radius);
printf("%f \n",area);
return 0;
}
float circle( r) /* with one parameter even no parameter type */
{
float a;
a=3.14*r*r;
return (a);
}
The
float circle();
is not a function with zero parameters. It's a function with an unspecified number of parameters.
The
float circle( r) {
is a K&R-style definition in which the type of r defaults to int. See https://stackoverflow.com/a/18433812/367273
This is because compiler treat r as int by default when no parameter is defined for circle. Try to run your code after declaring function prototype as
float circle(void);
and you will get error.
That's because function
float circle();
declaration doesn't declare function that takes no arguments.
It's implicitly declared as a function that takes undefined number of integer variables as arguments.
Just like
function();
is valid function declaration. Implicitly this function will be treated as function taking int as arguments and returning int.
If you want to declare function function taking no arguments or not returning any value, you do it with void keyword:
void funct(void);
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;
}
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How do you pass a function as a parameter in C?
Is it possible pass a function as a parameter in C? If yes, how?
No, you can't pass a 'function' as a parameter. You can, however, pass a pointer to a function instead.
When you reference a function by name without the parentheses for a function invocation, you are referencing a pointer to a function. Thus, for example, we could consider a function that generates a table of values for a mathematical function:
#include <math.h>
#include <stdio.h>
static void generator(double lo, double hi, double inc, double (*function)(double))
{
double x;
for (x = lo; x < hi; x += inc)
printf("x = %6g; f(x) = %6g\n", x, (*function)(x))
}
int main(void)
{
generator(0.0, 1.0, 0.02, sin);
generator(0.0, 1.0, 0.02, cos);
generator(0.0, 1.0, 0.02, sqrt);
return(0);
}
Here, the functions 'sin()', 'cos()', and 'sqrt()' all have the same prototype schema: function taking a double argument and returning a double value. Note that if I mistakenly wrote:
generator(0.0, 1.0, 0.02, sin());
I would get a bunch of compilation errors - one because 'sin()' expects an argument, and another because 'generator()' expects a pointer to a function and not a double value as the last argument.
(Also note that a good program would at least identify the function it is calculating, and the repeated increments of a double number is not a good idea for accuracy. It is but an example.)
Use a pointer to function.
Like int (*ptr2_fun)()
Receiving function being:
int execute_your_function(int (*fun)())
Here you have some examples
Use function pointers
Yes. Not a function per se but a pointer to a function instead.
See qsort().
int cmp(const void *a, const void *b) { /* ... */ }
/* ... */
qsort(data, nelems, sizeof *data, cmp); /* pass the function `cmp` to qsort() */
Great function pointer tutorial here:
http://www.newty.de/fpt/index.html
Sure, you can use a function pointer.
#include <stdio.h>
typedef void (*bar_callback)(void);
void foo(void)
{
puts("foo");
}
void bar(bar_callback callback)
{
puts("bar");
callback();
}
int main(int argc,char **argv)
{
bar(foo);
return 0;
}