1

So I need to write some code that performs partial integration. I have a numerical integrator schematically represented by

double integrate(double (*func)(double));

and suppose it works properly, i.e. for a function double f(double x), integrate(f) gives the right result. What I have instead, however, are functions that look like

double f(double x, double y);

and I want to perform integration on only the first variable - so dynamically generate pointers to functions like g(x)=f(x,1) or h(x)=f(x,2) and pass them to integrate. I guess prototypically what I want is to define a function within another,

double compute(double y){
  double g(double x){
    return f(x, y);
  }
  return integrate(g);
}

which I know is not part of ANSI C even though GCC allows it (maybe I shouldn't care and just use it then). So, what would be the standard, C18 approved way to get this behavior? If the only possibility is to copy over the code of integrate to the inside of compute, I guess I'll just use the GCC extension even though my LSP constantly complains about it, but I'm interested in what the "proper" program would look like.

6
  • Why do you want a “C99” way to do this? New programs should be written in C 2018 now. (This will not help with the problem in this question, but it should be general practice.) Commented Aug 30, 2022 at 19:09
  • Like this? double f(double, double); double g(double x) { return f(x, 1); } integrate(&g) Commented Aug 30, 2022 at 19:10
  • @EricPostpischil Oh, you're right. I sometimes forget the new standard exists since C99 is so ubiquitous. Commented Aug 30, 2022 at 19:16
  • Duplicate of Is there a a way to achieve closures in C? Commented Aug 30, 2022 at 19:34
  • @EricPostpischil From your statement it can likely be inferred that you agree with the design decisions in C18, and therefore don't mind depending on it. Commented Aug 31, 2022 at 1:59

1 Answer 1

2

Using the base C language, that is code that is strictly conforming as the standard defines it, here are three ways to do it.

Define a function that hard-codes the additional argument:

double g1(double x) { return f(x, 1); }
…
integrate(g1);

Define a function that gets the additional argument from an externally defined object:

double y;
double g(double x) { return f(x, y); }
…
y = 1;
integrate(g);

Modify integrate to take a pointer to additional information and use that to pass information to the function being integrated:

double integrate(double (*func)(double, const void *))

struct MyData { double y; }; // This structure can contain whatever you want.

double g(double x, const void *p)
{
    const struct MyData *data = p;
    return f(x, data->y);
}
…
struct MyData data = { 1 };
integrate(g, &data);

With GCC, you can use one of its extensions beyond the C standard that allows you to define functions within functions:

double compute(double y)
{
    double g(double x) { return f(x, y); }
    return integrate(g);
}

That can also be done in Clang using the blocks extension, but that would also require modifying integrate to accept a block.

Sign up to request clarification or add additional context in comments.

2 Comments

Important to note that even in GCC it does not do proper closures and you may not return g out of the function so still of limited utility and not much better than using the global variables.
Another approach is to have a function accept a pointer to a callback function pointer, and have it pass the received pointer to that function. If the function pointer is the first member of a structure type which is known to the callback function and the code which generates the object encapsulating the method, the callback function can cast the received pointer to that structure type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.