The Compiler


You went over Fortran 90 structures. Is there a Fortran 90 compiler on the Workstations?

Yes there is, but they have cleverly named it f77. This makes us long time programmers more comfortable, but adds to the confusion of new students of the subject.

How do you know if you are on a machine with 90 or 77?

Simplest answer is to give the compiler a small program containing a Fortran 90 statement. Other options include asking the system manager, typing the compiler name with no arguments ("f77"), or consulting "man". Always remember that the problems only work one direction. If you write a program, using only commands contained in Fortran 77, it will always compile and execute with a Fortran 90 compiler. I have tried to clearly state which statements and structures are unique to Fortran 90. The rest are Fortran 77.

When you use optimization options on the compiler is there any way to tell what part of the code the optimization has altered?

I have seen one or two compilers polite enough to provide messages on significant restructures of your program. Generally you can assume that there are small changes almost everywhere, but to tell the difference you need to know the assembly language for your machine. This compiler and most others will print assembly language (person readable machine language) for the compilation results.

I know you recommend using "f77 test.f -O" for the best level of optimization, but how does maximum optimization command, "f77 test.f -O3" hinder the way your program compiles when it maximizes the speed the most?

The -O3 option maximizes your exposure to compiler bugs. Choosing the -O options sometimes lets the compiler avoid trouble in regions where a forced maximum optimization might be a bad idea. By all means try -O3 when you you are ready to do serious number crunching, but don't trust your results until you have compared some sample results to those generated at lower optimization.

What directory is used by the compiler for compiling a Fortran Program? Where does f77 live?

For the work in this class, you should assume that everything happens in whatever directory you are in when you type the "f77". Type "pwd" if you don't know the answer to this question. The executable file called "f77" resides both in /bin and /usr/bin on these machines. This is very unsual. To locate an executable file use the "whereis" command (e.g. "whereis f77"). Unfortunately the manual pages on f77 aren't connected properly and are listed under IBM's other name for their compiler, "xlf". Try "man xlf" for more information on the compiler, but don't expect too much. IBM likes to force people to buy manuals and special CD-ROM packages.

Where can I get a Fortran Compiler for an IBM PC?

You can pick up one on the internet from the GNU project, but get a better package from MOC for about $80.00.

Is there a way to go back to the top of the error list after a failed compilation?

The Unix script command will save things for you in a file. If you are running a terminal emulator with a "scroll bar" on the side of the window. Try clicking in the scroll bar to see old stuff. Most of you probably won't have that option, so try one of the following:

f77 test.f >& testout

f77 -qsource test.f

The first dumps everything that would go to the screen (& picks up error messages which are treated as special cases by Unix) and puts the output into a file called "testout". It will complain and fail if "testout" already exists. The second will create a nice listing file called "test.lst" containing your source code and error messages.

When the main program is followed by a subprogram, why doesn't the compiler stop compiling when it hits the first END statement.

Fortran reads the entire contents of any ".f" file that you give it. The END statement just tells it that what follows is a separate program entity with limited shared information.

Does the computer compile everything between END statements separately.

Yes. Every time it hits an END statement, it compiles everything since the last END (or the beginning if no previous ENDs). The separate compilations are stuck together at the very end by a process called linking.

If we write a subroutine for someone else, how can we compile it to see if it will run before giving it to them?

This question gets to the heart of good programming practices. I'll give you an introduction here, and emphasize some of these points in later lectures. The easy part of the answer was hidden in the demonstration where I compiled 2 parts of a program separately and made a program on the 2nd partial compile. If you make a subroutine in a file called "subr1.f", you can compile to just test for Fortran errors with the command "f77 -c subr1.f". The "-c" option says just go through the compilation steps but don't make an executable code for me. This will leave a file behind called "subr1.o", which is almost machine instructions, and is ready to be linked to other stuff to make a full program. You're really not done yet. You should write a very short driver main program, that feeds some numbers to subr1 (call subr1(...)) for which you know the returned answer. You then check the known answers against the subroutine's answers before declaring victory. This testing is often easier said than done. Most useful subroutines do some fairly complicated calculations and contain IF tests that can result in different options being used depending on the input conditions. Designing test cases and checking methods can be challenging, but is essential. When approached systematically, this testing process is science at its best. You are in the business of constructing and interpreting controlled experiments. When using computers, most people simply treat them as an extension to theoretical science, another way to solve some equations. By recognizing the organized experimental aspects of creating and using computer programs you can give yourself a competitive advantage in this business.

I don't understand when you want to debug a program and you type f77 -g debug.f , to debug the program your working on, or is it a special program for debugging.

My choice of examples was poor. The file "debug.f" was just another Fortran program. I could have used the program "htcoef2.f". To prepare for debugging, I would have then typed:

f77 -g htcoef2.f

Please note that at this point, the only unusual thing I have done is to write some extra information to the executable file "a.out" for possible later use by the debugger. I can execute "a.out" just as before, and may never decide to do any debugging. The actual process of debugging begins when I type:

dbx a.out

I had trouble when I typed f77 to compile my 1st program. I was in the homework directory, do I have to be in the main directory? I was told by Unix that I had too many parameters when typing "f77 hw3.f".

The "too many parameters" message coming from Unix usually means you put a space somewhere you shouldn't like "hw3 .f". When you type the command you should be in the same directory as the file "hw3.f".

How do you use outside files that contain code in a program, and how is it brought in?

We have covered two ways. The first is appropriate when the outside files contain full subprograms. Then the file names must end with ".f", and you just list them on the compile line:

f77 main.f sub1.f sub2.f func.f

The compiler simply reads each file in turn and adds its contribution to the final executable file.

When the file just contains a segment of code, like a COMMON statement, you need to use an INCLUDE statement in your program, to tell the compiler to bring the contents of a file in for processing. What happens is that the compiler processes your statements in the original file until it hits and INCLUDE, then opens the listed file and processes everything in it. Once done with the INCLUDED file the compiler returns to processing the next line in your original file. If the file "more-code" contains the lines:

      real pi,g
      common/const/pi,g
and your program "test.f" contains:

      program test
      include 'more-code'
      print *,'Pi = ', pi,', g = ',g
      stop
      end
      blockdata constants
      include 'more-code'
      data pi,g/3.14159265,9.807/
      end
then the compiler is actually compiling the program:

      program test
         real pi,g
      common/const/pi,g
      print *,'Pi = ', pi,', g = ',g
      stop
      end
      blockdata constants
         real pi,g
      common/const/pi,g
      data pi,g/3.14159265,9.807/
      end


Up to other Questions and Answers / Home


Maintained by John Mahaffy : jhm@psu.edu