将Fortran 77代码转换为C ++

时间:2022-09-01 09:51:42

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 ?

有没有人将Fortran 77代码的大型(我们的550,000行)程序转换为C ++?你遇到了什么陷阱?转换成功了吗?你使用像for_c这样的工具(http://www.cobalt-blue.com/fc/fcmain.htm)吗?生成的C ++代码是显着更快还是更慢?

6 个解决方案

#1


9  

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.

这增加了EvilTeach的建议。请记住,链接Fortran 77和C / C ++代码相当容易,因此您可以逐步转换部分应用程序并将它们与旧部件链接在一起。如果你这样做,你将不得不考虑所有常见的fortran / c差异(行/列主要数组,数组索引等),但它可以节省你一次调试整个自动翻译代码库的痛苦。

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.

在国家(DOE)实验室中有许多这样的大型混合代码,它们对旧的Fortran代码进行了大量投资。如果你走这条路,你可以考虑使用Babel,它是为允许在同一个应用程序*享C,C ++,Fortran,Fortran90,Python和Java之间的组件而开发的。在实验室中实现这一目标的动机是将不同团队构建的物理模型捆绑在一起进行真正的大型模拟,但您可能会发现它对于转换代码也很有用。它在许多项目中得到了积极的维护和使用,尽管它可能对你想要做的事情来说有点过于复杂。

#2


9  

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.

真的有两条路可走。一种是直接逐行转换为c。我的意思是每个fortran声明给一个等于c的声明。

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.

另一条路径是重写,并且使用500k loc +,这将是更多的工作。有了这种大小,我当然会寻找一种工具来进行翻译,比如f2c。

Issues for a straight port...

直接端口的问题......

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

gotos直接翻译,你需要为goto目标创建标签。

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.

数组下标是一个重要的问题。 c是基于零的,fortran是基于1的,所以数组需要在fortran代码中标注一个更大的尺寸。

real*4 a(10,20) becomes

真正的* 4 a(10,20)变成了

#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.

c数组访问是行主要顺序,而fortran是列主要。这可能是一个性能问题。如果它确实成为一个问题,你可以用某种宏定义来解决它,这会颠倒顺序或数组下标。实际上你也可以让宏从每个下标中减去一个,以使它看起来像一个基于一个数组,实际上映射到一个基于零的数组。

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

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

fortran unit io可以使用stdio类型文件进行模拟。如果你使用单位19,那么

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.

如果您在文件中使用fortran托架控件,则可能存在托架控制问题。单元5和6可以简单地用stdin和stdout引用而不用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.

printf系列函数可以处理很多格式。您可能必须添加额外的循环来处理一些fortran数组io。

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

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

使用f2c可能是最快的方法。然后你被它的rtl困住了。 o做一个直接的港口是可行的事情。耗费时间,但如果你想长期保持它,我会推荐重写。非常耗时,可能更快,但从长远来看更易于维护

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.

令人高兴的是,在任何情况下,您都可以使用原始程序作为基线来进行一组单元测试,以帮助开发工作。

#3


6  

My reaction is why do you want to convert it.

我的反应是你为什么要转换它。

The question of how to develop a product with a large Fortran code base was looked at by numerous companies in the 1990's. That is whether to convert, stay with Fortran or produce a hybrid. I think the majority opted for the hybrid approach, usually C++ for the user interface and the original Fortran code base in the background.

在20世纪90年代,许多公司都在研究如何开发具有大量Fortran代码库的产品的问题。那就是转换,留在Fortran还是生产混合动力车。我认为大多数人选择了混合方法,通常是用户界面的C ++和后台的原始Fortran代码库。

My suggestion is to look at "Mixed language programming using C++ and FORTRAN 77" by Carsten Arnholm available at http://arnholm.org/software/cppf77/cppf77.htm In the earlier days of the internet this document was well linked to.

我的建议是查看Carsten Arnholm撰写的“使用C ++和FORTRAN 77的混合语言编程”,网址为http://arnholm.org/software/cppf77/cppf77.htm。在早期的互联网上,这个文档很好地链接到了。

This document describes how to have an application that contains C++ and Fortran. I cannot say whether some of the technical details may be outdated but this document came out of a project that wanted to using C++ for its development but had a huge Fortran code base.

本文档描述了如何使用包含C ++和Fortran的应用程序。我不能说一些技术细节是否可能已经过时,但是这个文档来自一个想要使用C ++进行开发但有一个庞大的Fortran代码库的项目。

You could also look at "Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples" by Barton and Nackman, available from good book stores. This book teaches C++ for Fortran programmers. It has a few examples of writing wrappers to Fortran code from C++. It is a good C++ book ignoring the Fortran aspect. It was written before the standard was set but the differences are not very big.

您还可以看看Barton和Nackman撰写的“科学与工程C ++:高级技术与实例介绍”,可从好书店获得。本书为Fortran程序员教授C ++。它有一些从C ++编写Fortran代码包装器的例子。这是一本很好的C ++书,忽略了Fortran方面。它是在标准设定之前编写的,但差异不是很大。

#4


3  

I once used this: http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html to convert a small fortran program to C. The conversion was successful. The code wasn't significantly complex to detect any kind of speed change.

我曾经用过这个:http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html将一个小的fortran程序转换为C.转换成功了。检测任何类型的速度变化的代码并不复杂。

Since your program is allot bigger I don't really know if everything is going to run like it did with me.

由于你的程序比较大,我真的不知道一切都会像我一样运行。

#5


2  

You might want to look into Promula. It produces more readable C code than many other automatic translators. I haven't used Promula directly, but I've converted a fair amount of Promula output from C to C++. It's easy to clean up the C code to legal C++, but of course it takes more effort to make it really good C++.

你可能想看看Promula。它产生比许多其他自动翻译器更可读的C代码。我没有直接使用Promula,但我已经将相当数量的Promula输出从C转换为C ++。将C代码清理成合法的C ++很容易,但当然需要花费更多精力才能使它成为真正优秀的C ++。

#6


0  

I've worked on a application that, at its heart, was code converted from FORTRAN using for_c . The code it created was god awful. It was very difficult to maintain since most of it was indecipherable. Luckily that code was pretty stable and it was rare that anything had to be done to it.

我已经开发了一个应用程序,其核心是使用for_c从FORTRAN转换的代码。它创造的代码太可怕了。由于大部分内容难以理解,因此很难维护。幸运的是,代码非常稳定,很少有必要对它进行任何操作。

However, this was done many years ago - circa the early 16-bit years of Windows. Maybe for_c is better now?

然而,这是在很多年前完成的 - 大约是Windows的早期16位年代。也许for_c现在更好?

#1


9  

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.

这增加了EvilTeach的建议。请记住,链接Fortran 77和C / C ++代码相当容易,因此您可以逐步转换部分应用程序并将它们与旧部件链接在一起。如果你这样做,你将不得不考虑所有常见的fortran / c差异(行/列主要数组,数组索引等),但它可以节省你一次调试整个自动翻译代码库的痛苦。

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.

在国家(DOE)实验室中有许多这样的大型混合代码,它们对旧的Fortran代码进行了大量投资。如果你走这条路,你可以考虑使用Babel,它是为允许在同一个应用程序*享C,C ++,Fortran,Fortran90,Python和Java之间的组件而开发的。在实验室中实现这一目标的动机是将不同团队构建的物理模型捆绑在一起进行真正的大型模拟,但您可能会发现它对于转换代码也很有用。它在许多项目中得到了积极的维护和使用,尽管它可能对你想要做的事情来说有点过于复杂。

#2


9  

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.

真的有两条路可走。一种是直接逐行转换为c。我的意思是每个fortran声明给一个等于c的声明。

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.

另一条路径是重写,并且使用500k loc +,这将是更多的工作。有了这种大小,我当然会寻找一种工具来进行翻译,比如f2c。

Issues for a straight port...

直接端口的问题......

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

gotos直接翻译,你需要为goto目标创建标签。

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.

数组下标是一个重要的问题。 c是基于零的,fortran是基于1的,所以数组需要在fortran代码中标注一个更大的尺寸。

real*4 a(10,20) becomes

真正的* 4 a(10,20)变成了

#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.

c数组访问是行主要顺序,而fortran是列主要。这可能是一个性能问题。如果它确实成为一个问题,你可以用某种宏定义来解决它,这会颠倒顺序或数组下标。实际上你也可以让宏从每个下标中减去一个,以使它看起来像一个基于一个数组,实际上映射到一个基于零的数组。

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

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

fortran unit io可以使用stdio类型文件进行模拟。如果你使用单位19,那么

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.

如果您在文件中使用fortran托架控件,则可能存在托架控制问题。单元5和6可以简单地用stdin和stdout引用而不用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.

printf系列函数可以处理很多格式。您可能必须添加额外的循环来处理一些fortran数组io。

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

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

使用f2c可能是最快的方法。然后你被它的rtl困住了。 o做一个直接的港口是可行的事情。耗费时间,但如果你想长期保持它,我会推荐重写。非常耗时,可能更快,但从长远来看更易于维护

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.

令人高兴的是,在任何情况下,您都可以使用原始程序作为基线来进行一组单元测试,以帮助开发工作。

#3


6  

My reaction is why do you want to convert it.

我的反应是你为什么要转换它。

The question of how to develop a product with a large Fortran code base was looked at by numerous companies in the 1990's. That is whether to convert, stay with Fortran or produce a hybrid. I think the majority opted for the hybrid approach, usually C++ for the user interface and the original Fortran code base in the background.

在20世纪90年代,许多公司都在研究如何开发具有大量Fortran代码库的产品的问题。那就是转换,留在Fortran还是生产混合动力车。我认为大多数人选择了混合方法,通常是用户界面的C ++和后台的原始Fortran代码库。

My suggestion is to look at "Mixed language programming using C++ and FORTRAN 77" by Carsten Arnholm available at http://arnholm.org/software/cppf77/cppf77.htm In the earlier days of the internet this document was well linked to.

我的建议是查看Carsten Arnholm撰写的“使用C ++和FORTRAN 77的混合语言编程”,网址为http://arnholm.org/software/cppf77/cppf77.htm。在早期的互联网上,这个文档很好地链接到了。

This document describes how to have an application that contains C++ and Fortran. I cannot say whether some of the technical details may be outdated but this document came out of a project that wanted to using C++ for its development but had a huge Fortran code base.

本文档描述了如何使用包含C ++和Fortran的应用程序。我不能说一些技术细节是否可能已经过时,但是这个文档来自一个想要使用C ++进行开发但有一个庞大的Fortran代码库的项目。

You could also look at "Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples" by Barton and Nackman, available from good book stores. This book teaches C++ for Fortran programmers. It has a few examples of writing wrappers to Fortran code from C++. It is a good C++ book ignoring the Fortran aspect. It was written before the standard was set but the differences are not very big.

您还可以看看Barton和Nackman撰写的“科学与工程C ++:高级技术与实例介绍”,可从好书店获得。本书为Fortran程序员教授C ++。它有一些从C ++编写Fortran代码包装器的例子。这是一本很好的C ++书,忽略了Fortran方面。它是在标准设定之前编写的,但差异不是很大。

#4


3  

I once used this: http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html to convert a small fortran program to C. The conversion was successful. The code wasn't significantly complex to detect any kind of speed change.

我曾经用过这个:http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html将一个小的fortran程序转换为C.转换成功了。检测任何类型的速度变化的代码并不复杂。

Since your program is allot bigger I don't really know if everything is going to run like it did with me.

由于你的程序比较大,我真的不知道一切都会像我一样运行。

#5


2  

You might want to look into Promula. It produces more readable C code than many other automatic translators. I haven't used Promula directly, but I've converted a fair amount of Promula output from C to C++. It's easy to clean up the C code to legal C++, but of course it takes more effort to make it really good C++.

你可能想看看Promula。它产生比许多其他自动翻译器更可读的C代码。我没有直接使用Promula,但我已经将相当数量的Promula输出从C转换为C ++。将C代码清理成合法的C ++很容易,但当然需要花费更多精力才能使它成为真正优秀的C ++。

#6


0  

I've worked on a application that, at its heart, was code converted from FORTRAN using for_c . The code it created was god awful. It was very difficult to maintain since most of it was indecipherable. Luckily that code was pretty stable and it was rare that anything had to be done to it.

我已经开发了一个应用程序,其核心是使用for_c从FORTRAN转换的代码。它创造的代码太可怕了。由于大部分内容难以理解,因此很难维护。幸运的是,代码非常稳定,很少有必要对它进行任何操作。

However, this was done many years ago - circa the early 16-bit years of Windows. Maybe for_c is better now?

然而,这是在很多年前完成的 - 大约是Windows的早期16位年代。也许for_c现在更好?