15

I'm trying to convert a Fortan77 program to C#. I have a subroutine with about 650 lines of code and horrific GOTO statements all over the place. I'm having a lot of trouble even starting to visualise the flow of the subroutine to figure out what it does.

Is there anybody with experience in this sort of thing who could give me any advice on how to get an overview of this subroutine? Are there some tools available to speed up or facilitate this type of conversion?

8
  • 1
    As this question is more open ended and looking for advice, it would be more appropriate on Programmers SE
    – Alastair Pitts
    Nov 30, 2011 at 6:08
  • 5
    have you considered just compiling it into .NET using silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx and then just referencing the assembly?
    – Shaun Wilde
    Nov 30, 2011 at 6:11
  • @Shaun, that's a nice idea Shaun. I will look at that if I can't get anywhere with the reprogramming.
    – user643192
    Nov 30, 2011 at 6:25
  • 2
    I feel sorry for you...
    – marko
    Nov 30, 2011 at 11:51
  • 1
    I've been in your place. It was worst days of my career.
    – user
    Sep 7, 2012 at 4:50

10 Answers 10

10

In my experience, a good way to go about this is to create a flow-chart of the Fortran code. Try to separate out the targets of the GOTO statements into separate blocks, and use the diagram to try to understand the code on a high level.

See if you can logically replace the GOTOs with loops or function calls; if the resulting diagram is in the form of a tree-structure, it is relatively easy to convert to C# without resorting to GOTOs. In the end though, you will need to understand the code intimately to be able to maintain and use the result with confidence.

10
  • Good suggestion, thanks! GOTO statements should be banned.
    – user643192
    Nov 30, 2011 at 6:23
  • 6
    @user643192, goto is an extremely useful thing if applied wisely. You would not go implementing an efficient, large state automaton without a goto. You'll certainly need them in your generated code as well.
    – SK-logic
    Nov 30, 2011 at 7:38
  • 3
    There are tools that can draw flowcharts from Fortran code. Example: home.comcast.net/~lchen223621
    – NoChance
    Nov 30, 2011 at 8:24
  • OP: You cannot ban retro-effectively. @EmmadKareem: Very useful suggestion.
    – Kris
    Nov 30, 2011 at 9:32
  • I ended up doing what Daniel B here suggested and made a block version of the Fortran code. It helped greatly, so thanks for that. To SK-logic, you are probably right about the GOTOs. My comment was made after my first afternoon looking at the code... and there are LOTS of GOTOs in it :o(
    – user643192
    Dec 2, 2011 at 5:15
12

In addition to what Daniel B wrote above, I would say the following:

First, get your Fortran code to work with Fortran for DotNet. Not if you "can't get anywhere with the reprogramming", but before you attempt any reprogramming. It will be a small step, but in the right direction.

Then, write a test suite in C# which feeds the Fortran code with whatever input it was made to munch on, and stores the output. Run the test suite once, and save the output. Then, extend the test suite to test the produced output against the saved output. Assuming that the Fortran code always produces the same output when fed the same input, the test should of course succeed.

Then, while you are rewriting the code in C#, you will be running your code under the test suite, and it will be telling you whether your code is working properly or not, meaning, whether it is producing the exact same output as the Fortran code given the same input. Without it, you will be lost.

I do not agree with @SK-logic, you should NOT have to use any gotos at all in your C# code.

(But hopefully once you have made the Fortran code work under DotNet you will see no reason to continue wasting your time converting a piece of spaghetti code to C#.)

7
  • 2
    mind explaining, why "you should NOT"? Any rational arguments, besides "everyone believes that it is evil"? I named two extremely important cases where you have to use goto, otherwise you'll end up writing either unreadable or unefficient code (or both).
    – SK-logic
    Nov 30, 2011 at 8:58
  • @SK-logic I did not write "you should NOT", I wrote "you should NOT have to". In any case, here it goes: goto statements make code very hard to comprehend and verify its correctness under almost all circumstances, and their supposed efficiency benefits are something between a myth and a misconception. Of course these could be further clarified, but please let's refrain from doing that, this is not the place for this discussion. Let us just agree to disagree.
    – Mike Nakis
    Nov 30, 2011 at 9:08
  • 2
    an absense of goto statemens can also make you code very hard to comprehend in some cases (and a state machine is the most important example of such a case). I just can't stand this stupid goto-bashing religion - people keep repeating the same meaningless BS without ever trying to understand the reason why goto is considered harmful.
    – SK-logic
    Nov 30, 2011 at 9:20
  • You are one of those people who just cannot stand it if they don't have the last word, eh? C-:=
    – Mike Nakis
    Nov 30, 2011 at 9:22
  • 1
    @ridecar2, I write good state machines ALL THE TIME. I use enums and switch statements, and I let the compiler write the GOTOs in the generated machine language. I have actually never seen an example of a state machine explicitly written with GOTOs. Care to post a pointer to an example? Apr 10, 2012 at 12:12
3

Your task is tricky. You really need to know Fortran well. You have to be careful about how similar/different Fortran does calculations and what rules of truncation and rounding apply. Also, you need to be careful about the primitive types meaning in C# and Fortran.

Another approach from what has been suggestion (not necessarily a better one, it is just another one):

A - Consider re-writing the code in C# based on the business knowledge and the function, use the Fortran code just as a reference

B -Consider using a commercial tool that does the conversion job - Example: DataTek

If the routine represents a standard function or a function that you can buy a ready made dll for (such as numerical integration), use the standard function or the commercial product instead of manual translation, and your problem is solved.

If the above does not cut it, answer this question:

Do I need to optimize the code or just make it run. In other words, what is the business value of spending 500 hours to make the code better?

if there is no value in optimization, translate the code line by line and you are done.

If this is still not good, then:

0-Convert the Fortran code line by line into C# (or use Fortan CLR)

1-Do a quick test make sure it runs

2-Use a re-factoring (commercial tools are available) to help you write the code in a more optimized fashion.

Good luck.

2

A simple way of recoding stuff with lots of gotos is to draw a flowchart and pull the string straight. Sometimes, F77 programs are just old F66 programs or even worse FII programs. F66 did not have an if-then-else construct so gotos were necessary. All you need to do is invert the condition to get an if-then.

F66 did not have a do-while either but F77 does. It depends on whether the coder was a convert from F66 to F77 (like many today are C to C++ or C++ to C#) where they are using F77 like F66. If you can spot the patterns, in the coding, it is far easier to convert.

1

Before you get started, make a test suite to test the existing code. Be very thorough as this will help shed light on the behavior. You can then use this suite to gauge tne effectiveness of your conversion.

Beyond that, be methodical, don't rush, and use lots of paper to trace out the functionality.

1

Here is the way I actually went about translating the code into C#. Since .NET supports goto statements I first took the entire Fortran code and pasted it as is into a new method, well, as many methods as there were Fortran routines and subroutines.

The compiler came up with a million errors, mostly about undeclared variables and incorrect block statement formatting, which I cleared up one by one. I also had to rewrite some of the Fortran-specific code, like I/O statements and stuff like that. When that was done I had an exact replica of the original code.

Thanks to the nice formatting of Visual Studio the logical blocks were a lot easier to identify than in the original code. And I could start unravelling the goto statements one by one.

From this experience I have to say that there are some cases where goto statements are actually VERY useful to avoid having to rewrite the same code over and over again, although in a lot of cases the same can be achieved by using methods and calling those repeatedly.

I also used the free version of Silverfrost to compile the original code and perfrom regular checks on my reformatted code to ensure that the reformatting didn't produce errors.

0

A generic approach to "decompiling" such a code would be the following:

  • first compile it into a lower level form (e.g., LLVM)
  • perform an SSA-transform on it (it will help to clean up your local variables)
  • split the irreducible control flow (if any)
  • detect loops and ifs and replace them with the proper high level constructs

LLVM's own C backend can provide you with a first draft.

0

The best way without doubt is to first rewrite/refactor the FORTRAN code into a better structured and logical way. This will force you to understand the original logic before attempting to port it to C#.

Here's how I would approach it:

  • Understand the existing code and if necessary refactor and even rewrite it in FORTRAN so you can test easily that it works.
  • Port the refactored code to C#

Don't waste your time with an automatic code converter which will just end up with the same mess of goto statements as the original FORTRAN since C# supports gotos and labels, just as C does.

0

Failing anything else, you can use goto statements in C#.

The goto statement transfers the program control directly to a labeled statement.

A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.

The goto statement is also useful to get out of deeply nested loops...

-2

To convert any old FORTRAN code to a new language somebody should go through some basic steps in your legacy code (1) for static type checking convert the code to "IMPLICIT NONE" (2) convert all truncated common to full common (3) Remove equivalence (4) convert common to Module of FORTRAN 90

Then you can try to convert to other languages.

Not the answer you're looking for? Browse other questions tagged or ask your own question.