"void value not ignored as it ought to be" but I'm lost where exactly I assign void to anything?

I am writing a code to integrate some ODEs using a leapfrog method, I have to supply a function including the derivatives to my integration method, however I’m getting a "void value not ignored as it ought to be error". I’ve gotten this in the past when I’ve mistaken types with function pointers but as far as I can see the function doesn’t assign anything anywhere, it should just execute?

So my source file is here

#include "nrutil.h"
#include <math.h>
#include <stdio.h>
void leapvel(int n, double x[], double v[], double dt2, void (*derivs)(double, double [], double []))

{
        double dvdt[n];
        int i;

        (*derivs)(n, x, dvdt);

        for(i = 0; i < n; i++)
                 v[i] += dt2*dvdt[i];

}

void output(int n, double x[], double v[], double t, double dt, void (*derivs)(double, double [], double []))
{
        int i;
        double vv[n], dvdt[n];

        printf("%f", t);
        for(i = 0; i < n; i++)
                printf(" %f", x[i]);

        /*sync velocity*/

        for (i = 0; i < n; i ++)
                vv[i] = v[i];
        if (t > 0)
        {
                (*derivs)(n,x,dvdt);
                for (i = 0; i < n; i ++)
                        vv[i] -= 0.5*dt*dvdt[i];
        }

        printf("\n");
}

void leap(int n, double x[], double v[], double* t, double dt, void (*derivs)(double, double [], double []))
{
        double dvdt[n];
        int i;

        for (i = 0; i < n; i++)
                x[i] += dt*v[i];

        (*derivs)(n, x, dvdt);

        for (i = 0; i < n; i++)
                v[i] += dt*dvdt[i];

        *t += dt;
}

void leapfrog(int n, double x[], double v[], double t, double dt, double t_max, void (*derivs)(double, double [], double []))
{
/* integration time! */

/* parameters, the user has to set these, and to be honest it's going to be cumbersome either way in command line or just editing the code */
/* but since we have to run this twice! */

/* double t = 0, x[n] = {0}, v[n] = {1};
double t_max = 15, dt = 1;*/

/*this is the number of equations in derivs*/
/*int n = 1*/

int i;


output(n, x, v, t, dt, *derivs);
leapvel(n, x, v, 0.5*dt, *derivs);

while (t < t_max)
{
        leap(n, x, v, &t, dt, *derivs);
        output(n, x, v, t, dt, *derivs);
}

}

This is referenced in a short file I do intend to make a header once I figure this out as it’s better practice than simply just including the source file however, for now this is what I have

#include <math.h>


void leapfrog(int n, double x[], double v[], double t, double dt, double t_max, void (*derivs)(double, double [], double []));

void derivs(int n, double x[], double dvdt[])
{
        int i;
        double accel = 0.0;

        for(i = 0; i < n; i++)
        {
                accel = -x[i];
                dvdt[i] = accel;
        }


}

int main()
{

/*frog goes {number of equations], {x initial conditions}, {v initial}, [t bottom], [t step], [t max], derivs(n,
 * x[], dvdt[]) */
int n = 1;
double x[n];
double v[n];
x[0] = 0;
v[0] = 1;

double t = 0;
double dt = 1;
double t_max = 15;
double dvdt[n];


leapfrog(n, x, v, t, dt, t_max, *derivs(n, x, dvdt)); /*I get the error on this line*/

return 0;

}

I’m probably missing something obvious here but I’m not sure.

I’ve tried to make the function a void pointer type function but that obviously is dangerous, and has undefined behavior, so I have a pointer to a void function now, but that gives this error. If I remove the arguments it has other weird behavior. I’m not sure how to make this work. Removing the arguments gives too few arguments obviously as it’s declare above, but when I give it what it wants it gives the error.

This means the error is probably in the source file shown off first, but I can’t seem to find it in there, as far as I can see I don’t directly assign it to anything so all should be fine.

>Solution :

If you want to pass the function derivs as an argument to a function, you just write derivs. Just like the way you pass any other variable. You don’t write sin(double x); it’s just sin(x). Same with functions.

Here, you are calling derivs and then attempting to dereference its non-existent return value:

leapfrog(n, x, v, t, dt, t_max, *derivs(n, x, dvdt))

The compiler objects, because there is obvious no return value to dereference. But the real error was writing a function call rather than just providing the function. You should write:

leapfrog(n, x, v, t, dt, t_max, derivs)

For obscure reasons, the compiler might not complain about this incorrect function call:

output(n, x, v, t, dt, *derivs);

where you are attempting to pass the function itself rather than a pointer to a function. If you look at the prototype for output, you’ll see that the last parameter is a pointer to a function, so that’s what you should pass it. Anyway, there is no other option, because in C functions are not usable as objects; you can only use pointers to functions. So that call (and the other similar ones) should be written as output(n, x, v, t, dt, derivs). Unsurprisingly, that’s pretty similar to the way leapfrog should be called.

Leave a Reply