CONTENTS
The tests have been done on Silicon Graphics (IRIX 4.0.1 and 5.3), DEC MIPS ULTRIX, DEC Alpha (Digital UNIX), and Sun OS 4.1.3.
The supercomputers Cray Y-MP (UNICOS 8.0.3.1), MasPar, and Parsytec are also discussed.
The results are rather conflicting, some combinations are permitted on some systems but not on others. Unfortunately, not all three compilers have been available for me on all the tested systems.
The main program in Fortran is in the file "f2sam.f" and is conventional. The subroutine and the function are in the file "sam.f". Running in Fortran is quite normal.
% cat f2sam.f program f2sam external f integer f character*7 s integer b(3) call sam(f, b(2), s) write(6,10) b(2), f(real(b(2))), s 10 format(i5,i5,10x,a7) stop end % cat sam.f subroutine sam(f, b, s) external f character*7 s integer b, f x = 1.3 s = 'Bo G E ' b = f(x) end integer function f(x) f=3*x**3 return endThe corresponding routine in C is in the file "c2sam.c" and has the following peculiarities:
% cat c2sam.c #include <stdio.h> #include <math.h> /* C Call to SAM in Fortran */ int f_(float *); main() { char s[7]; int b[3]; float x; sam_(f_, &b[1], s, 7); x = b[1]; printf(" %d %d %s \n ", b[1], f_(&x), s); }Compilation is done separately for the two languages, the switch -c interrupts the process after the assembly.
Linking is normal if the main program is in Fortran, if it is in C some extra libraries have to be mentioned explicitly.
Compilation and linking in the Fortran case
% f77 -c f2sam.f % f77 -c sam.f % f77 -o all f2sam.o sam.o % all 6 648 Bo G ECompilation and linking in the C case on Silicon Graphics (IRIX 4.0.1)
% cc -c c2sam.c % f77 -c sam.f % cc -o all c2sam.o sam.o -lF77 % all 6 648 Bo G EOn Silicon Graphics with IRIX 5.3 this also worked, but the output was appended with some rubbish! I have not yet found the reason for this irregularity. Also with the GNU compiler, gcc version 2.6.3, exactly the same happened.
Compilation and linking in the C case on Sun OS 4.1.3, using the GNU compiler, gcc version 2.3.3, and Fortran 77:
% gcc -c c2sam.c % f77 -c sam.f % gcc -o all c2sam.o sam.o -lF77 -lm % all 6 648 Bo G Eor with Fortran 90:
% gcc -c c2sam.c % f90 -c sam.f % gcc -o all c2sam.o sam.o /usr/local/lib/f90/libf90.a % all 6 648 Bo G EWith Fortran as the linker, the result was "Undefined: __main" for both Fortran 77 and Fortran 90 combined with the gcc compiler.
On Sun the compilation failed with the default C compiler (not ANSI-C).
On DEC MIPS ULTRIX no specification of extra libraries were required in most cases. I used all eight combinations of f77, f90, cc and gcc (version 2.5.8). With Fortran 77 or Fortran 90 and the GNU compiler the Fortran linking failed "Undefined: __main". Using the Fortran 90 compiler and linking with any C linker required explicit mentioning of the Fortran 90 library
cc sam.o c2sam.o /usr/local/NAGWare_f90/lib/libf90.a gcc sam.o c2sam.o /usr/local/NAGWare_f90/lib/libf90.a
On DEC Alpha (Digital UNIX) I used f90 and cc. It worked without extra libraries with C as the linking language, but failed with Fortran 90 ("c2sam.o: main: " multiply defined and "MAIN__" unresolved).
The main program in Fortran is in the file "mlp3.f" and is completely conventional.
% cat mlp3.f integer a(2,3) call p(a,1,3) write (6,10) a(1,3) 10 format (1x,I9) stop endWe perform the assignment in the C-routine p in the file "mlp4.c". This routine has the following peculiarities:
% cat mlp4.c #include <stdio.h> #include <math.h> /* Array Handling */ void p_(a,i,j) int *i, *j, a[3][2]; { a[*j-1][*i-1] = 99; }Compilation is done separately for the two languages, the switch "-c" interrupts the process after the assembly.
% cc -c mlp4.c % f77 -c mlp3.fLinking is normal if the most important program is in Fortran, if it is in C a lot of libraries have to be mentioned explicitly. Note that the choice of "most important" may be quite arbitrary.
% f77 -o alla mlp3.o mlp4.o % alla 99 % cc -o allac mlp3.o mlp4.o -lF77 -lI77 -lisam % allac 99The above works with both IRIX 4.0.1 and IRIX 5.3. When using IRIX 5.3 and gcc, both the Fortran and the gcc linking worked fine.
On the Sun OS 4.1.3 the standard method worked with f77 and with gcc the libraries "-lF77 -lm" were required, while with the default cc only "-lF77" was required.
Switching to Fortran 90 there were still no problems if Fortran was the linking language, but linking with cc required explicit mentioning of "/usr/local/lib/f90/f90lib.a" and linking with gcc in addition required the "-lm" switch.
On DEC MIPS ULTRIX no specification of extra libraries were required when Fortran was used as the linker. I used all eight combinations of f77, f90, cc and gcc (version 2.5.8). Using the Fortran 77 compiler and linking with any C linker required an impressive command
% cc mlp3.o mlp4.o -lfor -lutil -li -lots -lUfor % gcc mlp3.o mlp4.o -lfor -lutil -li -lots -lUforUsing the Fortran 90 compiler and linking with any C linker required explicit mentioning of the Fortran 90 library
% cc mlp3.o mlp4.o /usr/local/NAGWare_f90/lib/libf90.a % gcc mlp3.o mlp4.o /usr/local/NAGWare_f90/lib/libf90.aOn DEC Alpha (Digital UNIX) I used f90 and cc. It worked with Fortran 90 without any explicit libraries, but failed with C as the linking language (unresolved "main"), when I used the following command:
% cc -o all mlp3.o mlp4.o -lfor -lutil -lots
We put the COMMON block into the subroutine "sam" in the file "mlp2.f". It is completely conventional.
% cat mlp2.f subroutine sam() common /namn/ i, r i = 786 r = 3.2 return endThe main program in C is in the file "mlp1.c" and has the following peculiarities:
% cat mlp1.c #include <stdio.h> #include <math.h> /* Accessing Common Blocks of Data */ struct S {int i; float r;} namn_; main() { sam_(); printf(" %d %f\n",namn_.i,namn_.r); }Compilation is done separately for the two languages, the switch "-c" interrupts the process after the assembly.
% cc -c mlp1.c % f77 -c mlp2.fLinking is normal on all the tested systems.
% f77 -o all mlp1.o mlp2.o % all 786 3.200000 % cc -o allc mlp1.o mlp2.o % allc 786 3.200000Note that on the Silicon Graphics the Fortran system produces a much longer (in this case a factor 4) executable program than the C system.
% lls 331 -rwxr-xr-x 1 boein 169464 Aug 17 13:50 all* 81 -rwxr-xr-x 1 boein 40988 Aug 17 13:51 allc* %The above works with both IRIX 4.0.1 and IRIX 5.3. When using IRIX 5.3 and gcc, the Fortran linker complained about unresolved "__main", but the gcc linking worked fine.
On the Sun OS 4.1.3 the standard method worked both with f77 and f90 and the default cc.
Compiling with the GNU compiler gcc, the f77 or f90 linking did not work, resulting in an error message "Undefined symbol __main". Linking with gcc worked fine.
On DEC MIPS ULTRIX I used all eight combinations of f77, f90, cc and gcc (version 2.5.8). Everything worked with the exception of using a Fortran linker with a procedure compiled with the GNU C compiler. In these cases "Undefined: __main" was obtained.
On DEC Alpha (Digital UNIX) I used f90 and cc. It worked fine with C as the linking language, but failed with Fortran 90, complaining about multiply defined "main" and unresolved "MAIN__".
* Worked without any explicit libraries + Worked with explicit libraries - Failed E Compilation errorFor each operating system, the first symbol refers to Fortran as the linker, the second to C as the linker. For blank cases I do not have a compiler of the required kind.
Example | Languages | DEC | SGI | Sun | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
(section) | Unix | Ultrix | 4.0.1 | 5.3 | 4.1.3 | |||||||
2 | f77 | cc | * | * | * | + | * | + | E | E | ||
f77 | gcc | - | * | - | + | - | + | |||||
f90 | cc | - | * | * | + | E | E | |||||
f90 | gcc | - | + | - | + | |||||||
3 | f77 | cc | * | + | * | + | * | + | * | + | ||
f77 | gcc | * | + | * | + | * | + | |||||
f90 | cc | * | - | * | + | * | + | |||||
f90 | gcc | * | + | * | + | |||||||
4 | f77 | cc | * | * | * | * | * | * | * | * | ||
f77 | gcc | - | * | - | * | - | * | |||||
f90 | cc | - | * | * | * | * | * | |||||
f90 | gcc | - | * | - | * |
With the Cray method, at least one of the program units to be mixed has to be changed. The implementation is thus of "transportability" and not of "portability".
The Cray chapter 11 contains several examples and additional references to other relevant Cray documents.
I have tried mixed language programming on MasPar MP-1 without any success so far. The linker did not find the routines.
Reference: Parallel Processing: A Self-Study Introduction, A First Course in Programming the DECmpp/Sx, Ron Pickering and Jeremy Cook, para//ab, Department of Informatics, University of Bergen, N-5020 BERGEN, Norway. Available as the file "DECmpp_study_guide.ps.Z" from "ftp.ii.uib.no" in the directory "/pub/tech_reports".
I have tried mixed language programming on Parsytec without any success so far. The linker did not find the routines. The manuals I have checked do not mention mixed language programming or interlanguage communication.
It is possible to mix procedures written in FORTRAN 77, 90, classical C, and standard C and there are no particular constraints in this area.
On most computers, only the conventional C used to be available, but now ANSI C dominates. It is only on the Sun OS 4.1.3 where I have the old version of C, but luckily I also have the new one available as the GNU C, gcc. The big difference is a new syntax for declaring and defining functions. The old was like Fortran in that nothing was checked, while the new is like Algol in that a lot is checked. To use ANSI-C thus increases the safety.
Another change is the introduction of single precision. In conventional C all computations were performed in double precision on ordinary computers (but in single precision on the Cray). In addition records and unions, who have existed in many C-implementations, have been added to the standard, and finally the arithmetic properties have been clarified.
You should note the backward compatibility in that the old way of declaring functions has been kept as a permitted alternative. Because of the increased safety I strongly urge you to adapt to the new form.
A simple program in the old variant of C looks like
% cat tpk.c #include <stdio.h> #include <math.h> /* Function */ double fun(t) double t; { return t*t; } /* Program in C */ main() { int i; double t; double y; double a[11]; for ( i = 0; i <= 10; i++ ) { t = i; y = fun(t); printf(" %lf \n",y); } }As an ANSI-C program it becomes
% cat tpk-ansi.c #include <stdio.h> #include <math.h> /* Function declared */ double fun(double t); /* Program in C */ main() { /* No changes */ } /* Function defined */ double fun(double t) { return t*t; }In this paper I have mainly discussed ANSI-C. It is only on the Sun I have the conventional C. Some of the examples are from old manuals for the Silicon Graphics, using IRIX System V Release 3.3.1. Some revision has been done because of compiler development.
The used Fortran 90 compiler has been the NAGWare f90 Compiler (Unix), except on the Cray and the DEC Unix, where the compiler from the hardware manufacturer has been used.
At the presentation Eric Grosse made two suggestions, which I will look into:
Another question was about mixed language programming on PC:s. This was not covered in the talk. Some references are those by Microsoft and NAG in the bibliography.
For references please see my bibliograhy on mixed language programming.
My own papers on mixed language programming are listed here.