I have a C program that calls a Fortran function. I’m getting the below compiler error message. Can you give me examples on how to fix this with a C prototype?
error: implicit declaration of function ‘test_’ [-Werror=implicit-function-declaration]
`if (test_(&x, y, &z) != 0);`
INTEGER FUNCTION TEST(A,B,C)
REAL B(*)
INTEGER A,B
RETURN
END
int main ()
{
int x;
float y;
int z;
if (test_(&x, y, &z) != 0)
printf ("Yes \n");
}
C test.f
C
INTEGER(C_INT) FUNCTION TEST(A,B,C) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT, C_INT
REAL(C_FLOAT) B(*)
INTEGER(C_INT) A, C ! note the error in your Fortran routine
TEST = 42_C_INT
RETURN
END
// main.c
#include <stdio.h>
int test(int *a, float *b, int *c); // missing declaration in your main program
// no need for trailing underscore '_' due to
// BIND(C) attribute on the Fortran side
int main()
{
int x;
float y;
int z;
if (test(&x, &y, &z) != 0)
printf ("Yes \n");
}
Note the usage of BIND(C) as the standard way of overcoming compiler name mangling issues. You also won’t have to carry the trailing _ around anymore.
Putting a bit more effort into your minimal working example would go a long way.
In principle a compiler may choose to change the name mangling scheme between versions and render your code useless even on the same OS/compiler. Also if you put your procedure(s) in a module then the module name will probably be included in the name mangling and renaming the module would again break your code.
iso_c_binding is there to reduce clutter and errors, not the opposite.
The underscore at the end of your function call in main.c is the result of the name mangling scheme of your fortran compiler. Name mangling - Wikipedia
It’s not documented, but thismight be the way gfortran currently does name mangling:
Current GFortran name mangling
------------------------------
Currently the name mangling is a bit ad-hoc, with several different
prefixes depending on which part of the compiler is used:
- Procedure "foo" in module "bar": __bar_MOD_foo
- Runtime library: _gfortran_XXX
- Runtime library internal functions (not visible if symbol visibility
is supported): _gfortrani_XXX
- ISO_C_BINDING functions in the library: __iso_c_binding_XXX
- OOP stuff: __class_XXX