Prototype for calling Fortran function with a vector and two integers from C program

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");
}
1 Like
$ gfortran -c test.f
$ gcc main.c test.o -o main
$ ./main
Yes 
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.

Can’t this be accomplished without ISO_C_BINDING?

What will happen if I, instead, only define this prototype:

int test(int *a, float *b, int *c);

With just this one line, my code doesn’t give an error for the line of C code that calls the Fortran function.

ISO_C_BINDING involves more code which can be considered clutter by some people, not me of course! :woman_factory_worker:

I do believe that people can be prejudiced to what they perceive to be unnecessary clutter if they only want the code to work on a specific operating system and aren’t planning for other contingencies.

If I were to take my code containing all this “ISO_C_BINDING” stuff and give it to some people they’d twist it from my hands and then look for ways to get rid of me.

Maybe this thread should be for people to sound off to explain to me “all” the great benefits of using “ISO_C_BINDING” versus not using it. Can anyone state the tradeoffs (for example readability), so that I can understand the alternatives better?

I recently ordered two books describing “ISO_C_BINDING.” Do you have a more practical book or books that you can recommend? (Ideally, I’m looking for many practical and examples in a book.)

So, I have at my desk: (1) Metcalf, Reid, Cohen, “Modern Fortran Explained” and (2) Milan Curic, “Modern Fortran.”

Thank you,

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.

2 Likes

What’s this all about? Can you give me examples?

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 this might 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

My, entirely personal, advice would be to “run, do not walk” from such a workplace.

The “ISO_C_BINDING stuff” is how Fortran talks to C and vice versa. Everything else is technical debt.

3 Likes