Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interoperability of C variadic function and Fortran

Is there a way to declare a C variadic function and call it from Fortran? I need to call this function to compute some dot products between vectors labeled with a string. My idea was to declare something like the following, where the variable list of arguments contains string literals. If the variable list of arguments is empty, then I would do a lookup among the standard labels and perform the calculation. If the user specified two labels I would retrieve those two vectors and get their dot product:

extern "C" void compute_dot_product(double * dot_product, ...)
{
    va_list args;
    va_start(args, NULL);
    char * label1 = va_arg(args, char *);
    if (!label1)
    {
       // Do standard label lookup and compute dot product
    }
    else
    {
       // Compute dot product between the vectors with the specified labels
       char * label2 = va_arg(args, char *);
    }
    va_end(args);
}

the only problem is that I can compile my C library and link it to a Fortran executable, but I get a runtime error when I try to access the variable list of arguments. Any idea if what I am trying to do is possible? A possible solution would then be to split into two functions: one that does the standard label lookup (0 argument case), the other that handles the non-standard label lookup (2 argument case). I would rather avoid this solution though.

like image 658
boberto Avatar asked Oct 30 '13 02:10

boberto


1 Answers

It is not possible to call a variadic function in a standard conforming (i.e. portable) way.

You could make the definition of the C function take two parameters only (so it is no longer variadic - existing references to the function would need to be modified), with the second parameter in the C function a pointer, either NULL to indicate that there are no additional things being passed, or pointing at an array of pointers (perhaps NULL terminated) or whatever, with any additional things. In F201X an interface body for this sort of function might be able to use the OPTIONAL attribute for the second argument.

like image 131
IanH Avatar answered Sep 24 '22 09:09

IanH