Преобразование кода Fortran 77 в C ++ - PullRequest
14 голосов
/ 09 ноября 2008

Кто-нибудь конвертировал большую (у нас 550 000 строк) программу с кодом Fortran 77 в C ++? С какими подводными камнями вы столкнулись? Было ли преобразование успешным? Вы использовали такой инструмент, как for_c (http://www.cobalt -blue.com / fc / fcmain.htm )? Получился ли код C ++ значительно быстрее или медленнее?

Ответы [ 6 ]

9 голосов
/ 09 ноября 2008

Это добавляет к совету EvilTeach. Имейте в виду, что связать код Fortran 77 и C / C ++ довольно просто, так что вы можете постепенно преобразовывать части своего приложения и связывать их вместе со старыми частями. Если вы сделаете это, вам придется подумать обо всех обычных расхождениях в fortran / c (массивы строк / столбцов, индексирование массивов и т. Д.), Но это избавит вас от необходимости отладки всей вашей переведенной базы кода сразу. .

Есть много больших гибридных кодов, подобных этому, в национальных лабораториях (DOE), которые вкладывают значительные средства в старый код Fortran. Если вы пойдете по этому пути, вы можете рассмотреть возможность использования Babel , который был разработан для обеспечения совместного использования компонентов в C, C ++, Fortran, Fortran90, Python и Java в одном приложении. Мотивация для этого в лабораториях - связать физические модели, созданные разными командами, для действительно больших симуляций, но вы также можете найти это полезным для переноса своего кода. Он активно поддерживается и используется во многих проектах, хотя он может быть слишком сложным для того, что вы пытаетесь сделать.

9 голосов
/ 09 ноября 2008

Есть много вещей, чтобы рассмотреть.

Есть два пути. Одним из них является прямое построчное преобразование в c. Под этим я подразумеваю каждое утверждение с Фортрана в эквивалентном утверждении с.

Другой путь - переписать, и с 500k loc + это будет гораздо больше работы. При таком размере я бы, конечно, искал инструмент для перевода, например, f2c.

Проблемы с прямым портом ...

gotos переводит напрямую, вам нужно будет создать ярлыки для целей goto.

label10:;

    goto label10;

Подписка на массив является потенциальной проблемой. c основано на нуле, fortran - на основе 1, поэтому размеры массивов должны быть на единицу больше в коде fortran.

реальное * 4 a (10,20) становится

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

позволяя циклу быть написанным так.

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

c Доступ к массиву осуществляется в основном порядке строк, в то время как fortran - основной столбец. это может быть проблемой производительности. если это станет проблемой, вы можете чтобы решить это с помощью какого-то макроопределения, которое меняет порядок или индексы массива. Фактически, вы также можете сделать так, чтобы макрос вычитал по одному из каждого из индексов, чтобы он выглядел как массив на основе одного, фактически отображая массив на основе нуля.

real * 8 a (XMAX, YMAX) а (4,2) = 3,14

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

fortran unit io можно моделировать с помощью файлов типа stdio. если вы используете юнит 19, то

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

Могут возникнуть проблемы с контролем каретки, если вы используете в ваших файлах контроль каретки fortran. На блоки 5 и 6 можно просто ссылаться с помощью stdin и stdout без fopen.

Многие форматы могут обрабатываться с помощью семейства функций printf. Возможно, вам придется добавить дополнительные циклы для работы с массивом fortran io.

ЗАПИСЬ (6, 200) (PROJ (z, 4), z = 1, 20)

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


o использование f2c, вероятно, самый быстрый способ сделать это. Тогда вы застряли с его RTL.
Выполнение прямого порта - вполне осуществимая вещь. Трудоемкий, но выполнимый
o если вы хотите сохранить его в долгосрочной перспективе, я бы порекомендовал переписать. Очень много времени, вероятно, быстрее, но более долговечно в обслуживании

К счастью, в любом случае у вас есть исходная программа, которую можно использовать в качестве основы для создания набора модульных тестов, помогающих в разработке.

6 голосов
/ 10 июня 2009

Моя реакция - почему вы хотите преобразовать это.

Вопрос о том, как разработать продукт с большой кодовой базой на языке Fortran, рассматривался многими компаниями в 1990-х годах. То есть нужно ли конвертировать, остаться с Фортраном или произвести гибрид. Я думаю, что большинство выбрали гибридный подход, обычно C ++ для пользовательского интерфейса и исходную базу кода Fortran в фоновом режиме.

Мое предложение состоит в том, чтобы взглянуть на «Программирование на разных языках с использованием C ++ и FORTRAN 77» Карстена Арнхольма, доступное по адресу http://arnholm.org/software/cppf77/cppf77.htm В более ранние дни Интернета этот документ был хорошо связан с.

Этот документ описывает, как иметь приложение, которое содержит C ++ и Fortran. Я не могу сказать, могут ли некоторые технические детали быть устаревшими, но этот документ вышел из проекта, который хотел использовать C ++ для своей разработки, но имел огромную базу кода Fortran.

Вы также можете посмотреть «Научно-технический проект C ++: Введение с передовыми методами и примерами» Бартона и Нэкмана, который можно найти в хороших книжных магазинах. Эта книга преподает C ++ для фортрановских программистов. В нем есть несколько примеров написания оболочек для кода на Фортране из C ++. Это хорошая книга по С ++, игнорирующая аспект Фортрана. Он был написан до того, как был установлен стандарт, но различия не очень велики.

3 голосов
/ 09 ноября 2008

Однажды я использовал это: http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html, чтобы преобразовать небольшую фортран-программу в C. Преобразование прошло успешно. Код не был достаточно сложным, чтобы обнаружить любое изменение скорости.

Поскольку ваша программа намного больше, я не знаю, будет ли все работать так же, как со мной.

2 голосов
/ 09 ноября 2008

Возможно, вы захотите посмотреть Promula . Он производит более читаемый код C, чем многие другие автоматические переводчики. Я не использовал Promula напрямую, но конвертировал изрядную сумму Promula из C в C ++. Легко очистить код C до легального C ++, но, конечно, требуется больше усилий, чтобы сделать его действительно хорошим C ++.

0 голосов
/ 18 июня 2009

Я работал над приложением, которое по своей сути было преобразовано из кода FORTRAN с использованием for_c . Код, который он создал, был ужасен. Поддерживать его было очень сложно, так как большая часть его была неразборчива. К счастью, этот код был довольно стабилен, и редко что-либо предпринималось с ним.

Однако, это было сделано много лет назад - в начале 16-битных лет Windows. Может быть, for_c лучше сейчас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...