In addition to my top comments, Fortran passes by reference, so you have to modify the .c and the .for files.

The code below works. There may be a simpler way to declare things, but this should [at least] get you further along. Caveat: I haven't done much fortran since Fortran IV days, so I'm a bit rusty. I'd defer to Vladimir's VALUE solution as a better way to go.

#include <stdio.h> #if 0 extern int fact_(int n); extern void pythagoras_(float a, float b, float *c); #else extern int fact_(int *n); extern void pythagoras_(float *a, float *b, float *c); #endif int main(void) { float c; #if 0 printf("Factorial of 7 is: %d

", fact_(7)); #else int n = 7; printf("Factorial of 7 is: %d

", fact_(&n)); #endif #if 0 pythagoras_(30, 40, &c); #else float a = 30; float b = 40; pythagoras_(&a, &b, &c); #endif printf("Hypotenuse if sides 30, 40 is: %f

", c); return 0; }

INTEGER*4 FUNCTION Fact (n) INTEGER*4 n INTEGER*4 i, amt amt = 1 DO i = 1, n amt = amt * i END DO Fact = amt END SUBROUTINE Pythagoras (a, b, c) REAL*4 a REAL*4 b REAL*4 c c = SQRT (a * a + b * b) END

Here is the program output:

Factorial of 7 is: 5040 Hypotenuse if sides 30, 40 is: 50.000000

UPDATE:

I get the same undefined reference error from your code!

Aha!

One thing I didn't mention [because I didn't think it would make a difference] is that I changed the source file names to use all lowercase letters (e.g. CMAIN.C --> cmain.c and FORSUBS.FOR --> forsubs.for )

With that, the output of nm *.o produces:

cmain.o: U fact_ 0000000000000000 T main U printf U pythagoras_ forsubs.o: 0000000000000000 T fact_ 0000000000000045 T pythagoras_

The change in the fortran source filename doesn't matter too much. But, the C source filename does!

More to the point it's the filename suffix (i.e. .C changed to .c ).

This is because gcc will [try to be smart and] look at the suffix to determine which language the file is written in and compile accordingly. For example, gcc -c foo.cpp will compile the file as if it is written in c++ and not c , just as if the command were: g++ -c foo.cpp

Although .cpp is the [more] usual suffix for a c++ filename, an alternate suffix for c++ files is: .C

That is, most projects use the .cpp convention, but some use the .C convention. One of the reasons for preferring .cpp over .C is that Windows filesystems are case insensitive. So, .C and .c would appear the same. However, POSIX systems (e.g. linux, macOSX, iOS, android, etc.) have case sensitive filenames so either convention can be used.

So, gcc -c CMAIN.C will compile as c++ . This does c++ style "name mangling" of symbols--not what we want. In c++ , the mangling is done to allow "overloading" of function names. That is, two [or more] different functions can have the same name, as long as they use different arguments. For example:

void calc(int val); void calc(int val1,int val2); void calc(double fval);

Here is the output of nm *.o if we use CMAIN.C :

CMAIN.o: 0000000000000000 T main U printf U _Z11pythagoras_PfS_S_ U _Z5fact_Pi FORSUBS.o: 0000000000000000 T fact_ 0000000000000045 T pythagoras_

Running that file through c++filt to "demangle" the c++ names we get:

CMAIN.o: 0000000000000000 T main U printf U pythagoras_(float*, float*, float*) U fact_(int*) FORSUBS.o: 0000000000000000 T fact_ 0000000000000045 T pythagoras_