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 ?
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).
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!
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).
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With