Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conversion of Fortran 77 code to C++

Has anyone converted a large (ours is 550,000 lines) program of Fortran 77 code to C++ ? What pitfalls did you run into ? Was the conversion a success ? Did you use a tool like for_c ( http://www.cobalt-blue.com/fc/fcmain.htm ) ? Was the resulting C++ code significantly faster or slower ?

like image 209
Lynn McGuire Avatar asked Nov 09 '08 01:11

Lynn McGuire


People also ask

What is C in Fortran?

A most peculiar feature of Fortran 77 is its line structure, which is a carryover from the old days when programs were typed on punch cards. A punch card had 80 columns, and so does a line of Fortran code. A "c" in column 1 indicates a comment (similar to REM in Basic).

Which column is used for continuation character in Fortran 77?

Column 6 is used to indicate that the statements is a continuation of the previous statement/line. A FORTRAN 77 statement may be up to 40 lines long!

How do I convert CPP to C code?

Originally Answered: How can we convert a C++ program to a C language program? Just switch all the non compiled file names from . cpp to . c and .o, then set the code that uses only C code then —— Just declare the C++ function extern "C" (in your C++ code) and call it (from your C or C++ code).

What is Fortran syntax?

Basics. Fortran has a set of rules used to determine whether a program is valid and can be understood by the computer, a bit like a human language. The combination of keywords and characters that are used to form Fortran programs are usually referred to as the language's syntax.


2 Answers

This adds to EvilTeach's advice. Keep in mind that it's fairly easy to link Fortran 77 and C/C++ code, so you can convert parts of your application incrementally and link them together with the old parts. You'll have to think about all the usual fortran/c discrepancies (row/column-major arrays, array indexing, etc.) if you do this, but it would save you the pain of debugging your entire auto-translated codebase at once.

There are many large hybrid codes like this at the national (DOE) labs, which have a significant investment in old Fortran code. If you go this route, you might consider using Babel, which was developed to allow components to be shared between C, C++, Fortran, Fortran90, Python and Java all in the same app. The motivation for this at the labs is tying together physics models built by different teams for really large simulations, but you might find it useful for transitioning your code, too. It's actively maintained and used on a lot of projects, though it might be a bit too complex for what you're trying to do.

like image 190
Todd Gamblin Avatar answered Sep 16 '22 18:09

Todd Gamblin


There are a lot of things to consider.

There are really two paths to take. One is to do a direct line by line conversion to c. By that I mean every fortran statement to an equalivant c statement.

The other path to take is a rewrite, and with 500k loc+ that would be much more work. With that kind of size, I certainly would look for a tool, to do the translation, like f2c.

Issues for a straight port...

gotos translate directly, you will need to create labels for the goto targets.

label10:;

    goto label10;

Array subscripting is a potiential problem. c is zero based, fortran is 1 based, so arrays need to be dimensioned one larger in the fortran code.

real*4 a(10,20) becomes

#define XMAX 10 + 1
#define YMAX 20 + 1 
float a[XMAX][YMAX];

allowing the loop to be written like this.

for (x = 1; x <= XMAX; x++)
    for (y = 1; y <= YMAX; y++)
        a[x][y] = 0.0f;

c array access is in row major order, while fortran is column major. that can be a performance problem. if it does become a problem, you may be able to solve it with some sort of macro definition which reverses the order or the array subscripts. In fact you could also have the macro subtract one off of each of the subscripts in order to make it look like a one based array, actually map to a zero based array.

real*8 a(XMAX,YMAX) a(4,2) = 3.14

#define A(X,Y)  a[Y][X]
double a[XMAX][YMAX];
A(4,2) = 3.14;

fortran unit io can be simulated with stdio type files. if you are using unit 19, then

FILE *fp19 = fopen("file","mode");

There may be issues with carriage control if you are using fortran carriage control in your files. Units 5 and 6 can be simply referenced with stdin, and stdout without fopen.

A lot of formats can be handled with the printf family of functions. You may have to add additional loops to deal with some of the fortran array io.

WRITE(6, 200) (PROJ(z,4),z = 1, 20)

int z;
for (z = 1, z <= 20; z++)
    printf("%lf ", proj[z][4]);


o using f2c is probably the fastest way to do it. Then you are stuck with its rtl.
o doing a direct port is a feasable thing to do. Time consuming, but doable
o if you want to maintain it long term, I would recommend a rewrite. Very time consuming, probably faster, but more maintainable in the long run

Happily in any case you have the original program to use as a baseline to make a set of unit tests to help in the development effort.

like image 36
9 revs Avatar answered Sep 16 '22 18:09

9 revs