     [file root.texi not included]

This file documents the use and the internals of the GNU Fortran (g77) compiler. It corresponds to the which-g77 version of g77.

Published by the Free Software Foundation 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA

Copyright © 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with the Invariant Sections being ``GNU General Public License'' and ``Funding Free Software'', the Front-Cover texts being (a) (see below), and with the Back-Cover Texts being (b) (see below).  A copy of the license is included in the section entitled ``GNU Free Documentation License''.

(a) The FSF's Front-Cover Text is:

A GNU Manual

(b) The FSF's Back-Cover Text is:

You have freedom to copy and modify this GNU Manual, like GNU software.  Copies published by the Free Software Foundation raise funds for GNU development.

Contributed by James Craig Burley (email-burley). Inspired by a first pass at translating g77-0.5.16/f/DOC that was contributed to Craig by David Ronis (ronis@onsager.chem.mcgill.ca).

Introduction
************

This manual documents how to run, install and port g77, as well as its new features and incompatibilities, and how to report bugs. It corresponds to the which-g77 version of g77.

     [file gpl.texi not included]

     [file fdl.texi not included]

Contributors to GNU Fortran
***************************

In addition to James Craig Burley, who wrote the front end, many people have helped create and improve GNU Fortran.

  * The packaging and compiler portions of GNU Fortran are based largely on the GCC compiler. See Contributors to GCC (Using the GNU Compiler Collection (GCC)), for more information.

  * The run-time library used by GNU Fortran is a repackaged version of the libf2c library (combined from the libF77 and libI77 libraries) provided as part of f2c, available for free from netlib sites on the Internet.

  * Cygnus Support and The Free Software Foundation contributed significant money and/or equipment to Craig's efforts.

  * The following individuals served as alpha testers prior to g77's public release.  This work consisted of testing, researching, sometimes debugging, and occasionally providing small amounts of code and fixes for g77, plus offering plenty of helpful advice to Craig:

       Jonathan Corbet

       Dr. Mark Fernyhough

       Takafumi Hayashi (The University of Aizu)---takafumi@u-aizu.ac.jp

       Kate Hedstrom

       Michel Kern (INRIA and Rice University)---Michel.Kern@inria.fr

       Dr. A. O. V. Le Blanc

       Dave Love

       Rick Lutowski

       Toon Moene

       Rick Niles

       Derk Reefman

       Wayne K. Schroll

       Bill Thorson

       Pedro A. M. Vazquez

       Ian Watson

  * Dave Love (d.love@dl.ac.uk) wrote the libU77 part of the run-time library.

  * Scott Snyder (snyder@d0sgif.fnal.gov) provided the patch to add rudimentary support for INTEGER*1, INTEGER*2, and LOGICAL*1. This inspired Craig to add further support, even though the resulting support would still be incomplete. This support is believed to be completed at version 3.4 of gcc by Roger Sayle (roger@eyesopen.com).

  * David Ronis (ronis@onsager.chem.mcgill.ca) inspired and encouraged Craig to rewrite the documentation in texinfo format by contributing a first pass at a translation of the old g77-0.5.16/f/DOC file.

  * Toon Moene (toon@moene.indiv.nluug.nl) performed some analysis of generated code as part of an overall project to improve g77 code generation to at least be as good as f2c used in conjunction with gcc. So far, this has resulted in the three, somewhat experimental, options added by g77 to the gcc compiler and its back end.

     (These, in turn, had made their way into the egcs version of the compiler, and do not exist in gcc version 2.8 or versions of g77 based on that version of gcc.)

  * John Carr (jfc@mit.edu) wrote the alias analysis improvements.

  * Thanks to Mary Cortani and the staff at Craftwork Solutions (support@craftwork.com) for all of their support.

  * Many other individuals have helped debug, test, and improve g77 over the past several years, and undoubtedly more people will be doing so in the future. If you have done so, and would like to see your name listed in the above list, please ask! The default is that people wish to remain anonymous.

     [file funding.texi not included]

Funding GNU Fortran
*******************

James Craig Burley (email-burley), the original author of g77, stopped working on it in September 1999 (He has a web page at www-burley.)

GNU Fortran is currently maintained by Toon Moene (toon@moene.indiv.nluug.nl), with the help of countless other volunteers.

As with other GNU software, funding is important because it can pay for needed equipment, personnel, and so on.

The FSF provides information on the best way to fund ongoing development of GNU software (such as GNU Fortran) in documents such as the ``GNUS Bulletin''. Email gnu@gnu.org for information on funding the FSF.

Another important way to support work on GNU Fortran is to volunteer to help out.

Email email-general to volunteer for this work.

However, we strongly expect that there will never be a version 0.6 of g77.  Work on this compiler has stopped as of the release of GCC 3.1, except for bug fixing.  g77 will be succeeded by g95 - see http://g95.sourceforge.net.

See Funding Free Software, for more information.

Getting Started
***************

If you don't need help getting started reading the portions of this manual that are most important to you, you should skip this portion of the manual.

If you are new to compilers, especially Fortran compilers, or new to how compilers are structured under UNIX and UNIX-like systems, you'll want to see What is GNU Fortran?.

If you are new to GNU compilers, or have used only one GNU compiler in the past and not had to delve into how it lets you manage various versions and configurations of gcc, you should see G77 and GCC.

Everyone except experienced g77 users should see Invoking G77.

If you're acquainted with previous versions of g77, you should see News About GNU Fortran. Further, if you've actually used previous versions of g77, especially if you've written or modified Fortran code to be compiled by previous versions of g77, you should see Changes.

If you intend to write or otherwise compile code that is not already strictly conforming ANSI FORTRAN 77---and this is probably everyone---you should see Language.

If you run into trouble getting Fortran code to compile, link, run, or work properly, you might find answers if you see Debugging and Interfacing, see Collected Fortran Wisdom, and see Trouble. You might also find that the problems you are encountering are bugs in g77---see Bugs, for information on reporting them, after reading the other material.

If you need further help with g77, or with freely redistributable software in general, see Service.

If you would like to help the g77 project, see Funding GNU Fortran, for information on helping financially, and see Projects, for information on helping in other ways.

If you're generally curious about the future of g77, see Projects. If you're curious about its past, see Contributors, and see Funding GNU Fortran.

To see a few of the questions maintainers of g77 have, and that you might be able to answer, see Open Questions.

What is GNU Fortran?
********************

GNU Fortran, or g77, is designed initially as a free replacement for, or alternative to, the UNIX f77 command. (Similarly, gcc is designed as a replacement for the UNIX cc command.)

g77 also is designed to fit in well with the other fine GNU compilers and tools.

Sometimes these design goals conflict---in such cases, resolution often is made in favor of fitting in well with Project GNU. These cases are usually identified in the appropriate sections of this manual.

As compilers, g77, gcc, and f77 share the following characteristics:

  * They read a user's program, stored in a file and containing instructions written in the appropriate language (Fortran, C, and so on). This file contains source code.

  * They translate the user's program into instructions a computer can carry out more quickly than it takes to translate the instructions in the first place. These instructions are called machine code---code designed to be efficiently translated and processed by a machine such as a computer. Humans usually aren't as good writing machine code as they are at writing Fortran or C, because it is easy to make tiny mistakes writing machine code. When writing Fortran or C, it is easy to make big mistakes.

  * They provide information in the generated machine code that can make it easier to find bugs in the program (using a debugging tool, called a debugger, such as gdb).

  * They locate and gather machine code already generated to perform actions requested by statements in the user's program. This machine code is organized into libraries and is located and gathered during the link phase of the compilation process. (Linking often is thought of as a separate step, because it can be directly invoked via the ld command. However, the g77 and gcc commands, as with most compiler commands, automatically perform the linking step by calling on ld directly, unless asked to not do so by the user.)

  * They attempt to diagnose cases where the user's program contains incorrect usages of the language. The diagnostics produced by the compiler indicate the problem and the location in the user's source file where the problem was first noticed. The user can use this information to locate and fix the problem. (Sometimes an incorrect usage of the language leads to a situation where the compiler can no longer make any sense of what follows---while a human might be able to---and thus ends up complaining about many ``problems'' it encounters that, in fact, stem from just one problem, usually the first one reported.)

  * They attempt to diagnose cases where the user's program contains a correct usage of the language, but instructs the computer to do something questionable. These diagnostics often are in the form of warnings, instead of the errors that indicate incorrect usage of the language.

How these actions are performed is generally under the control of the user. Using command-line options, the user can specify how persnickety the compiler is to be regarding the program (whether to diagnose questionable usage of the language), how much time to spend making the generated machine code run faster, and so on.

g77 consists of several components:

  * A modified version of the gcc command, which also might be installed as the system's cc command. (In many cases, cc refers to the system's ``native'' C compiler, which might be a non-GNU compiler, or an older version of gcc considered more stable or that is used to build the operating system kernel.)

  * The g77 command itself, which also might be installed as the system's f77 command.

  * The libg2c run-time library. This library contains the machine code needed to support capabilities of the Fortran language that are not directly provided by the machine code generated by the g77 compilation phase.

     libg2c is just the unique name g77 gives to its version of libf2c to distinguish it from any copy of libf2c installed from f2c (or versions of g77 that built libf2c under that same name) on the system.

     The maintainer of libf2c currently is dmg@bell-labs.com.

  * The compiler itself, internally named f771.

     Note that f771 does not generate machine code directly---it generates assembly code that is a more readable form of machine code, leaving the conversion to actual machine code to an assembler, usually named as.

gcc is often thought of as ``the C compiler'' only, but it does more than that. Based on command-line options and the names given for files on the command line, gcc determines which actions to perform, including preprocessing, compiling (in a variety of possible languages), assembling, and linking.

For example, the command gcc foo.c drives the file foo.c through the preprocessor cpp, then the C compiler (internally named cc1), then the assembler (usually as), then the linker (ld), producing an executable program named a.out (on UNIX systems).

As another example, the command gcc foo.cc would do much the same as gcc foo.c, but instead of using the C compiler named cc1, gcc would use the C++ compiler (named cc1plus).

In a GNU Fortran installation, gcc recognizes Fortran source files by name just like it does C and C++ source files. It knows to use the Fortran compiler named f771, instead of cc1 or cc1plus, to compile Fortran files.

Non-Fortran-related operation of gcc is generally unaffected by installing the GNU Fortran version of gcc. However, without the installed version of gcc being the GNU Fortran version, gcc will not be able to compile and link Fortran programs---and since g77 uses gcc to do most of the actual work, neither will g77!

The g77 command is essentially just a front-end for the gcc command. Fortran users will normally use g77 instead of gcc, because g77 knows how to specify the libraries needed to link with Fortran programs (libg2c and lm). g77 can still compile and link programs and source files written in other languages, just like gcc.

The command g77 -v is a quick way to display lots of version information for the various programs used to compile a typical preprocessed Fortran source file---this produces much more output than gcc -v currently does. (If it produces an error message near the end of the output---diagnostics from the linker, usually ld---you might have an out-of-date libf2c that improperly handles complex arithmetic.) In the output of this command, the line beginning GNU Fortran Front End identifies the version number of GNU Fortran; immediately preceding that line is a line identifying the version of gcc with which that version of g77 was built.

The libf2c library is distributed with GNU Fortran for the convenience of its users, but is not part of GNU Fortran. It contains the procedures needed by Fortran programs while they are running.

For example, while code generated by g77 is likely to do additions, subtractions, and multiplications in line---in the actual compiled code---it is not likely to do trigonometric functions this way.

Instead, operations like trigonometric functions are compiled by the f771 compiler (invoked by g77 when compiling Fortran code) into machine code that, when run, calls on functions in libg2c, so libg2c must be linked with almost every useful program having any component compiled by GNU Fortran. (As mentioned above, the g77 command takes care of all this for you.)

The f771 program represents most of what is unique to GNU Fortran. While much of the libg2c component comes from the libf2c component of f2c, a free Fortran-to-C converter distributed by Bellcore (AT&T), plus libU77, provided by Dave Love, and the g77 command is just a small front-end to gcc, f771 is a combination of two rather large chunks of code.

One chunk is the so-called GNU Back End, or GBE, which knows how to generate fast code for a wide variety of processors. The same GBE is used by the C, C++, and Fortran compiler programs cc1, cc1plus, and f771, plus others. Often the GBE is referred to as the ``gcc back end'' or even just ``gcc''---in this manual, the term GBE is used whenever the distinction is important.

The other chunk of f771 is the majority of what is unique about GNU Fortran---the code that knows how to interpret Fortran programs to determine what they are intending to do, and then communicate that knowledge to the GBE for actual compilation of those programs. This chunk is called the Fortran Front End (FFE). The cc1 and cc1plus programs have their own front ends, for the C and C++ languages, respectively. These fronts ends are responsible for diagnosing incorrect usage of their respective languages by the programs the process, and are responsible for most of the warnings about questionable constructs as well. (The GBE handles producing some warnings, like those concerning possible references to undefined variables.)

Because so much is shared among the compilers for various languages, much of the behavior and many of the user-selectable options for these compilers are similar. For example, diagnostics (error messages and warnings) are similar in appearance; command-line options like -Wall have generally similar effects; and the quality of generated code (in terms of speed and size) is roughly similar (since that work is done by the shared GBE).

Compile Fortran, C, or Other Programs
*************************************

A GNU Fortran installation includes a modified version of the gcc command.

In a non-Fortran installation, gcc recognizes C, C++, and Objective-C source files.

In a GNU Fortran installation, gcc also recognizes Fortran source files and accepts Fortran-specific command-line options, plus some command-line options that are designed to cater to Fortran users but apply to other languages as well.

See Programming Languages Supported by GCC (Using the GNU Compiler Collection (GCC)), for information on the way different languages are handled by the GCC compiler (gcc).

Also provided as part of GNU Fortran is the g77 command. The g77 command is designed to make compiling and linking Fortran programs somewhat easier than when using the gcc command for these tasks. It does this by analyzing the command line somewhat and changing it appropriately before submitting it to the gcc command.

Use the -v option with g77 to see what is going on---the first line of output is the invocation of the gcc command.

     [file invoke.texi not included]

     [file news.texi not included]

     [file news.texi not included]

The GNU Fortran Language
************************

GNU Fortran supports a variety of extensions to, and dialects of, the Fortran language. Its primary base is the ANSI FORTRAN 77 standard, currently available on the network at http://www.fortran.com/fortran/F77_std/rjcnf0001.html or as monolithic text at http://www.fortran.com/fortran/F77_std/f77_std.html. It offers some extensions that are popular among users of UNIX f77 and f2c compilers, some that are popular among users of other compilers (such as Digital products), some that are popular among users of the newer Fortran 90 standard, and some that are introduced by GNU Fortran.

(If you need a text on Fortran, a few freely available electronic references have pointers from http://www.fortran.com/F/books.html.  There is a `cooperative net project', User Notes on Fortran Programming at ftp://vms.huji.ac.il/fortran/ and mirrors elsewhere; some of this material might not apply specifically to g77.)

Part of what defines a particular implementation of a Fortran system, such as g77, is the particular characteristics of how it supports types, constants, and so on. Much of this is left up to the implementation by the various Fortran standards and accepted practice in the industry.

The GNU Fortran language is described below. Much of the material is organized along the same lines as the ANSI FORTRAN 77 standard itself.

See Other Dialects, for information on features g77 supports that are not part of the GNU Fortran language.

Note: This portion of the documentation definitely needs a lot of work!

Direction of Language Development
=================================

The purpose of the following description of the GNU Fortran language is to promote wide portability of GNU Fortran programs.

GNU Fortran is an evolving language, due to the fact that g77 itself is in beta test. Some current features of the language might later be redefined as dialects of Fortran supported by g77 when better ways to express these features are added to g77, for example. Such features would still be supported by g77, but would be available only when one or more command-line options were used.

The GNU Fortran language is distinct from the GNU Fortran compilation system (g77).

For example, g77 supports various dialects of Fortran---in a sense, these are languages other than GNU Fortran---though its primary purpose is to support the GNU Fortran language, which also is described in its documentation and by its implementation.

On the other hand, non-GNU compilers might offer support for the GNU Fortran language, and are encouraged to do so.

Currently, the GNU Fortran language is a fairly fuzzy object. It represents something of a cross between what g77 accepts when compiling using the prevailing defaults and what this document describes as being part of the language.

Future versions of g77 are expected to clarify the definition of the language in the documentation. Often, this will mean adding new features to the language, in the form of both new documentation and new support in g77. However, it might occasionally mean removing a feature from the language itself to ``dialect'' status. In such a case, the documentation would be adjusted to reflect the change, and g77 itself would likely be changed to require one or more command-line options to continue supporting the feature.

The development of the GNU Fortran language is intended to strike a balance between:

  * Serving as a mostly-upwards-compatible language from the de facto UNIX Fortran dialect as supported by f77.

  * Offering new, well-designed language features. Attributes of such features include not making existing code any harder to read (for those who might be unaware that the new features are not in use) and not making state-of-the-art compilers take longer to issue diagnostics, among others.

  * Supporting existing, well-written code without gratuitously rejecting non-standard constructs, regardless of the origin of the code (its dialect).

  * Offering default behavior and command-line options to reduce and, where reasonable, eliminate the need for programmers to make any modifications to code that already works in existing production environments.

  * Diagnosing constructs that have different meanings in different systems, languages, and dialects, while offering clear, less ambiguous ways to express each of the different meanings so programmers can change their code appropriately.

One of the biggest practical challenges for the developers of the GNU Fortran language is meeting the sometimes contradictory demands of the above items.

For example, a feature might be widely used in one popular environment, but the exact same code that utilizes that feature might not work as expected---perhaps it might mean something entirely different---in another popular environment.

Traditionally, Fortran compilers---even portable ones---have solved this problem by simply offering the appropriate feature to users of the respective systems. This approach treats users of various Fortran systems and dialects as remote ``islands'', or camps, of programmers, and assume that these camps rarely come into contact with each other (or, especially, with each other's code).

Project GNU takes a radically different approach to software and language design, in that it assumes that users of GNU software do not necessarily care what kind of underlying system they are using, regardless of whether they are using software (at the user-interface level) or writing it (for example, writing Fortran or C code).

As such, GNU users rarely need consider just what kind of underlying hardware (or, in many cases, operating system) they are using at any particular time. They can use and write software designed for a general-purpose, widely portable, heterogeneous environment---the GNU environment.

In line with this philosophy, GNU Fortran must evolve into a product that is widely ported and portable not only in the sense that it can be successfully built, installed, and run by users, but in the larger sense that its users can use it in the same way, and expect largely the same behaviors from it, regardless of the kind of system they are using at any particular time.

This approach constrains the solutions g77 can use to resolve conflicts between various camps of Fortran users. If these two camps disagree about what a particular construct should mean, g77 cannot simply be changed to treat that particular construct as having one meaning without comment (such as a warning), lest the users expecting it to have the other meaning are unpleasantly surprised that their code misbehaves when executed.

The use of the ASCII backslash character in character constants is an excellent (and still somewhat unresolved) example of this kind of controversy. See Backslash in Constants. Other examples are likely to arise in the future, as g77 developers strive to improve its ability to accept an ever-wider variety of existing Fortran code without requiring significant modifications to said code.

Development of GNU Fortran is further constrained by the desire to avoid requiring programmers to change their code. This is important because it allows programmers, administrators, and others to more faithfully evaluate and validate g77 (as an overall product and as new versions are distributed) without having to support multiple versions of their programs so that they continue to work the same way on their existing systems (non-GNU perhaps, but possibly also earlier versions of g77).

ANSI FORTRAN 77 Standard Support
================================

GNU Fortran supports ANSI FORTRAN 77 with the following caveats. In summary, the only ANSI FORTRAN 77 features g77 doesn't support are those that are probably rarely used in actual code, some of which are explicitly disallowed by the Fortran 90 standard.

No Passing External Assumed-length
----------------------------------

g77 disallows passing of an external procedure as an actual argument if the procedure's type is declared CHARACTER*(*).  For example:

     CHARACTER*(*) CFUNC
     EXTERNAL CFUNC
     CALL FOO(CFUNC)
     END

It isn't clear whether the standard considers this conforming.

No Passing Dummy Assumed-length
-------------------------------

g77 disallows passing of a dummy procedure as an actual argument if the procedure's type is declared CHARACTER*(*).

     SUBROUTINE BAR(CFUNC)
     CHARACTER*(*) CFUNC
     EXTERNAL CFUNC
     CALL FOO(CFUNC)
     END

It isn't clear whether the standard considers this conforming.

No Pathological Implied-DO
--------------------------

The DO variable for an implied-DO construct in a DATA statement may not be used as the DO variable for an outer implied-DO construct.  For example, this fragment is disallowed by g77:

     DATA ((A(I, I), I= 1, 10), I= 1, 10) /.../

This also is disallowed by Fortran 90, as it offers no additional capabilities and would have a variety of possible meanings.

Note that it is very unlikely that any production Fortran code tries to use this unsupported construct.

No Useless Implied-DO
---------------------

An array element initializer in an implied-DO construct in a DATA statement must contain at least one reference to the DO variables of each outer implied-DO construct.  For example, this fragment is disallowed by g77:

     DATA (A, I= 1, 1) /1./

This also is disallowed by Fortran 90, as FORTRAN 77's more permissive requirements offer no additional capabilities. However, g77 doesn't necessarily diagnose all cases where this requirement is not met.

Note that it is very unlikely that any production Fortran code tries to use this unsupported construct.

Conformance
===========

(The following information augments or overrides the information in Section 1.4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 1 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

The definition of the GNU Fortran language is akin to that of the ANSI FORTRAN 77 language in that it does not generally require conforming implementations to diagnose cases where programs do not conform to the language.

However, g77 as a compiler is being developed in a way that is intended to enable it to diagnose such cases in an easy-to-understand manner.

A program that conforms to the GNU Fortran language should, when compiled, linked, and executed using a properly installed g77 system, perform as described by the GNU Fortran language definition. Reasons for different behavior include, among others:

  * Use of resources (memory---heap, stack, and so on; disk space; CPU time; etc.) exceeds those of the system.

  * Range and/or precision of calculations required by the program exceeds that of the system.

  * Excessive reliance on behaviors that are system-dependent (non-portable Fortran code).

  * Bugs in the program.

  * Bug in g77.

  * Bugs in the system.

Despite these ``loopholes'', the availability of a clear specification of the language of programs submitted to g77, as this document is intended to provide, is considered an important aspect of providing a robust, clean, predictable Fortran implementation.

The definition of the GNU Fortran language, while having no special legal status, can therefore be viewed as a sort of contract, or agreement. This agreement says, in essence, ``if you write a program in this language, and run it in an environment (such as a g77 system) that supports this language, the program should behave in a largely predictable way''.

Notation Used in This Chapter
=============================

(The following information augments or overrides the information in Section 1.5 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 1 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

In this chapter, ``must'' denotes a requirement, ``may'' denotes permission, and ``must not'' and ``may not'' denote prohibition. Terms such as ``might'', ``should'', and ``can'' generally add little or nothing in the way of weight to the GNU Fortran language itself, but are used to explain or illustrate the language.

For example:

     ``The FROBNITZ statement must precede all executable
     statements in a program unit, and may not specify any dummy
     arguments.  It may specify local or common variables and arrays.
     Its use should be limited to portions of the program designed to
     be non-portable and system-specific, because it might cause the
     containing program unit to behave quite differently on different
     systems.''

Insofar as the GNU Fortran language is specified, the requirements and permissions denoted by the above sample statement are limited to the placement of the statement and the kinds of things it may specify. The rest of the statement---the content regarding non-portable portions of the program and the differing behavior of program units containing the FROBNITZ statement---does not pertain the GNU Fortran language itself. That content offers advice and warnings about the FROBNITZ statement.

Remember: The GNU Fortran language definition specifies both what constitutes a valid GNU Fortran program and how, given such a program, a valid GNU Fortran implementation is to interpret that program.

It is not incumbent upon a valid GNU Fortran implementation to behave in any particular way, any consistent way, or any predictable way when it is asked to interpret input that is not a valid GNU Fortran program.

Such input is said to have undefined behavior when interpreted by a valid GNU Fortran implementation, though an implementation may choose to specify behaviors for some cases of inputs that are not valid GNU Fortran programs.

Other notation used herein is that of the GNU texinfo format, which is used to generate printed hardcopy, on-line hypertext (Info), and on-line HTML versions, all from a single source document. This notation is used as follows:

  * Keywords defined by the GNU Fortran language are shown in uppercase, as in: COMMON, INTEGER, and BLOCK DATA.

     Note that, in practice, many Fortran programs are written in lowercase---uppercase is used in this manual as a means to readily distinguish keywords and sample Fortran-related text from the prose in this document.

  * Portions of actual sample program, input, or output text look like this: Actual program text.

     Generally, uppercase is used for all Fortran-specific and Fortran-related text, though this does not always include literal text within Fortran code.

     For example: PRINT *, 'My name is Bob'.

  * A metasyntactic variable---that is, a name used in this document to serve as a placeholder for whatever text is used by the user or programmer---appears as shown in the following example:

     ``The INTEGER IVAR statement specifies that IVAR is a variable or array of type INTEGER.''

     In the above example, any valid text may be substituted for the metasyntactic variable IVAR to make the statement apply to a specific instance, as long as the same text is substituted for both occurrences of IVAR.

  * Ellipses (``...'') are used to indicate further text that is either unimportant or expanded upon further, elsewhere.

  * Names of data types are in the style of Fortran 90, in most cases.

     See Kind Notation, for information on the relationship between Fortran 90 nomenclature (such as INTEGER(KIND=1)) and the more traditional, less portably concise nomenclature (such as INTEGER*4).

Fortran Terms and Concepts
==========================

(The following information augments or overrides the information in Chapter 2 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 2 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

Syntactic Items
---------------

(Corresponds to Section 2.2 of ANSI X3.9-1978 FORTRAN 77.)

In GNU Fortran, a symbolic name is at least one character long, and has no arbitrary upper limit on length. However, names of entities requiring external linkage (such as external functions, external subroutines, and COMMON areas) might be restricted to some arbitrary length by the system. Such a restriction is no more constrained than that of one through six characters.

Underscores (_) are accepted in symbol names after the first character (which must be a letter).

Statements, Comments, and Lines
-------------------------------

(Corresponds to Section 2.3 of ANSI X3.9-1978 FORTRAN 77.)

Use of an exclamation point (!) to begin a trailing comment (a comment that extends to the end of the same source line) is permitted under the following conditions:

  * The exclamation point does not appear in column 6. Otherwise, it is treated as an indicator of a continuation line.

  * The exclamation point appears outside a character or Hollerith constant. Otherwise, the exclamation point is considered part of the constant.

  * The exclamation point appears to the left of any other possible trailing comment. That is, a trailing comment may contain exclamation points in their commentary text.

Use of a semicolon (;) as a statement separator is permitted under the following conditions:

  * The semicolon appears outside a character or Hollerith constant. Otherwise, the semicolon is considered part of the constant.

  * The semicolon appears to the left of a trailing comment. Otherwise, the semicolon is considered part of that comment.

  * Neither a logical IF statement nor a non-construct WHERE statement (a Fortran 90 feature) may be followed (in the same, possibly continued, line) by a semicolon used as a statement separator.

     This restriction avoids the confusion that can result when reading a line such as:

          IF (VALIDP) CALL FOO; CALL BAR

     Some readers might think the CALL BAR is executed only if VALIDP is .TRUE., while others might assume its execution is unconditional.

     (At present, g77 does not diagnose code that violates this restriction.)

Scope of Symbolic Names and Statement Labels
--------------------------------------------

(Corresponds to Section 2.9 of ANSI X3.9-1978 FORTRAN 77.)

Included in the list of entities that have a scope of a program unit are construct names (a Fortran 90 feature). See Construct Names, for more information.

Characters, Lines, and Execution Sequence
=========================================

(The following information augments or overrides the information in Chapter 3 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 3 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

GNU Fortran Character Set
-------------------------

(Corresponds to Section 3.1 of ANSI X3.9-1978 FORTRAN 77.)

Letters include uppercase letters (the twenty-six characters of the English alphabet) and lowercase letters (their lowercase equivalent). Generally, lowercase letters may be used in place of uppercase letters, though in character and Hollerith constants, they are distinct.

Special characters include:

  * Semicolon (;)

  * Exclamation point (!)

  * Double quote (")

  * Backslash (\)

  * Question mark (?)

  * Hash mark (#)

  * Ampersand (&)

  * Percent sign (%)

  * Underscore (_)

  * Open angle (<)

  * Close angle (>)

  * The FORTRAN 77 special characters (SPC, =, +, -, *, /, (, ), ,, ., $, ', and :)

Note that this document refers to SPC as space, while X3.9-1978 FORTRAN 77 refers to it as blank.

Lines
-----

(Corresponds to Section 3.2 of ANSI X3.9-1978 FORTRAN 77.)

The way a Fortran compiler views source files depends entirely on the implementation choices made for the compiler, since those choices are explicitly left to the implementation by the published Fortran standards.

The GNU Fortran language mandates a view applicable to UNIX-like text files---files that are made up of an arbitrary number of lines, each with an arbitrary number of characters (sometimes called stream-based files).

This view does not apply to types of files that are specified as having a particular number of characters on every single line (sometimes referred to as record-based files).

Because a ``line in a program unit is a sequence of 72 characters'', to quote X3.9-1978, the GNU Fortran language specifies that a stream-based text file is translated to GNU Fortran lines as follows:

  * A newline in the file is the character that represents the end of a line of text to the underlying system. For example, on ASCII-based systems, a newline is the NL character, which has ASCII value 10 (decimal).

  * Each newline in the file serves to end the line of text that precedes it (and that does not contain a newline).

  * The end-of-file marker (EOF) also serves to end the line of text that precedes it (and that does not contain a newline).

  * Any line of text that is shorter than 72 characters is padded to that length with spaces (called ``blanks'' in the standard).

  * Any line of text that is longer than 72 characters is truncated to that length, but the truncated remainder must consist entirely of spaces.

  * Characters other than newline and the GNU Fortran character set are invalid.

For the purposes of the remainder of this description of the GNU Fortran language, the translation described above has already taken place, unless otherwise specified.

The result of the above translation is that the source file appears, in terms of the remainder of this description of the GNU Fortran language, as if it had an arbitrary number of 72-character lines, each character being among the GNU Fortran character set.

For example, if the source file itself has two newlines in a row, the second newline becomes, after the above translation, a single line containing 72 spaces.

Continuation Line
-----------------

(Corresponds to Section 3.2.3 of ANSI X3.9-1978 FORTRAN 77.)

A continuation line is any line that both

  * Contains a continuation character, and

  * Contains only spaces in columns 1 through 5

A continuation character is any character of the GNU Fortran character set other than space (SPC) or zero (0) in column 6, or a digit (0 through 9) in column 7 through 72 of a line that has only spaces to the left of that digit.

The continuation character is ignored as far as the content of the statement is concerned.

The GNU Fortran language places no limit on the number of continuation lines in a statement. In practice, the limit depends on a variety of factors, such as available memory, statement content, and so on, but no GNU Fortran system may impose an arbitrary limit.

Statements
----------

(Corresponds to Section 3.3 of ANSI X3.9-1978 FORTRAN 77.)

Statements may be written using an arbitrary number of continuation lines.

Statements may be separated using the semicolon (;), except that the logical IF and non-construct WHERE statements may not be separated from subsequent statements using only a semicolon as statement separator.

The END PROGRAM, END SUBROUTINE, END FUNCTION, and END BLOCK DATA statements are alternatives to the END statement. These alternatives may be written as normal statements---they are not subject to the restrictions of the END statement.

However, no statement other than END may have an initial line that appears to be an END statement---even END PROGRAM, for example, must not be written as:

           END
          &PROGRAM

Statement Labels
----------------

(Corresponds to Section 3.4 of ANSI X3.9-1978 FORTRAN 77.)

A statement separated from its predecessor via a semicolon may be labeled as follows:

  * The semicolon is followed by the label for the statement, which in turn follows the label.

  * The label must be no more than five digits in length.

  * The first digit of the label for the statement is not the first non-space character on a line. Otherwise, that character is treated as a continuation character.

A statement may have only one label defined for it.

Order of Statements and Lines
-----------------------------

(Corresponds to Section 3.5 of ANSI X3.9-1978 FORTRAN 77.)

Generally, DATA statements may precede executable statements. However, specification statements pertaining to any entities initialized by a DATA statement must precede that DATA statement. For example, after DATA I/1/, INTEGER I is not permitted, but INTEGER J is permitted.

The last line of a program unit may be an END statement, or may be:

  * An END PROGRAM statement, if the program unit is a main program.

  * An END SUBROUTINE statement, if the program unit is a subroutine.

  * An END FUNCTION statement, if the program unit is a function.

  * An END BLOCK DATA statement, if the program unit is a block data.

Including Source Text
---------------------

Additional source text may be included in the processing of the source file via the INCLUDE directive:

     INCLUDE FILENAME

The source text to be included is identified by FILENAME, which is a literal GNU Fortran character constant. The meaning and interpretation of FILENAME depends on the implementation, but typically is a filename.

(g77 treats it as a filename that it searches for in the current directory and/or directories specified via the -I command-line option.)

The effect of the INCLUDE directive is as if the included text directly replaced the directive in the source file prior to interpretation of the program. Included text may itself use INCLUDE. The depth of nested INCLUDE references depends on the implementation, but typically is a positive integer.

This virtual replacement treats the statements and INCLUDE directives in the included text as syntactically distinct from those in the including text.

Therefore, the first non-comment line of the included text must not be a continuation line. The included text must therefore have, after the non-comment lines, either an initial line (statement), an INCLUDE directive, or nothing (the end of the included text).

Similarly, the including text may end the INCLUDE directive with a semicolon or the end of the line, but it cannot follow an INCLUDE directive at the end of its line with a continuation line. Thus, the last statement in an included text may not be continued.

Any statements between two INCLUDE directives on the same line are treated as if they appeared in between the respective included texts. For example:

     INCLUDE 'A'; PRINT *, 'B'; INCLUDE 'C'; END PROGRAM

If the text included by INCLUDE 'A' constitutes a PRINT *, 'A' statement and the text included by INCLUDE 'C' constitutes a PRINT *, 'C' statement, then the output of the above sample program would be

     A
     B
     C

(with suitable allowances for how an implementation defines its handling of output).

Included text must not include itself directly or indirectly, regardless of whether the FILENAME used to reference the text is the same.

Note that INCLUDE is not a statement. As such, it is neither a non-executable or executable statement. However, if the text it includes constitutes one or more executable statements, then the placement of INCLUDE is subject to effectively the same restrictions as those on executable statements.

An INCLUDE directive may be continued across multiple lines as if it were a statement. This permits long names to be used for FILENAME.

Cpp-style directives
--------------------

cpp output-style # directives (see C Preprocessor Output (The C Preprocessor)) are recognized by the compiler even when the preprocessor isn't run on the input (as it is when compiling .F files).  (Note the distinction between these cpp # output directives and #line input directives.)

Data Types and Constants
========================

(The following information augments or overrides the information in Chapter 4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 4 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

To more concisely express the appropriate types for entities, this document uses the more concise Fortran 90 nomenclature such as INTEGER(KIND=1) instead of the more traditional, but less portably concise, byte-size-based nomenclature such as INTEGER*4, wherever reasonable.

When referring to generic types---in contexts where the specific precision and range of a type are not important---this document uses the generic type names INTEGER, LOGICAL, REAL, COMPLEX, and CHARACTER.

In some cases, the context requires specification of a particular type. This document uses the KIND= notation to accomplish this throughout, sometimes supplying the more traditional notation for clarification, though the traditional notation might not work the same way on all GNU Fortran implementations.

Use of KIND= makes this document more concise because g77 is able to define values for KIND= that have the same meanings on all systems, due to the way the Fortran 90 standard specifies these values are to be used.

(In particular, that standard permits an implementation to arbitrarily assign nonnegative values. There are four distinct sets of assignments: one to the CHARACTER type; one to the INTEGER type; one to the LOGICAL type; and the fourth to both the REAL and COMPLEX types. Implementations are free to assign these values in any order, leave gaps in the ordering of assignments, and assign more than one value to a representation.)

This makes KIND= values superior to the values used in non-standard statements such as INTEGER*4, because the meanings of the values in those statements vary from machine to machine, compiler to compiler, even operating system to operating system.

However, use of KIND= is not generally recommended when writing portable code (unless, for example, the code is going to be compiled only via g77, which is a widely ported compiler). GNU Fortran does not yet have adequate language constructs to permit use of KIND= in a fashion that would make the code portable to Fortran 90 implementations; and, this construct is known to not be accepted by many popular FORTRAN 77 implementations, so it cannot be used in code that is to be ported to those.

The distinction here is that this document is able to use specific values for KIND= to concisely document the types of various operations and operands.

A Fortran program should use the FORTRAN 77 designations for the appropriate GNU Fortran types---such as INTEGER for INTEGER(KIND=1), REAL for REAL(KIND=1), and DOUBLE COMPLEX for COMPLEX(KIND=2)---and, where no such designations exist, make use of appropriate techniques (preprocessor macros, parameters, and so on) to specify the types in a fashion that may be easily adjusted to suit each particular implementation to which the program is ported. (These types generally won't need to be adjusted for ports of g77.)

Further details regarding GNU Fortran data types and constants are provided below.

Data Types
----------

(Corresponds to Section 4.1 of ANSI X3.9-1978 FORTRAN 77.)

GNU Fortran supports these types:

 1. Integer (generic type INTEGER)

 2. Real (generic type REAL)

 3. Double precision

 4. Complex (generic type COMPLEX)

 5. Logical (generic type LOGICAL)

 6. Character (generic type CHARACTER)

 7. Double Complex

(The types numbered 1 through 6 above are standard FORTRAN 77 types.)

The generic types shown above are referred to in this document using only their generic type names. Such references usually indicate that any specific type (kind) of that generic type is valid.

For example, a context described in this document as accepting the COMPLEX type also is likely to accept the DOUBLE COMPLEX type.

The GNU Fortran language supports three ways to specify a specific kind of a generic type.

Double Notation
...............

The GNU Fortran language supports two uses of the keyword DOUBLE to specify a specific kind of type:

  * DOUBLE PRECISION, equivalent to REAL(KIND=2)

  * DOUBLE COMPLEX, equivalent to COMPLEX(KIND=2)

Use one of the above forms where a type name is valid.

While use of this notation is popular, it doesn't scale well in a language or dialect rich in intrinsic types, as is the case for the GNU Fortran language (especially planned future versions of it).

After all, one rarely sees type names such as DOUBLE INTEGER, QUADRUPLE REAL, or QUARTER INTEGER. Instead, INTEGER*8, REAL*16, and INTEGER*1 often are substituted for these, respectively, even though they do not always have the same meanings on all systems. (And, the fact that DOUBLE REAL does not exist as such is an inconsistency.)

Therefore, this document uses ``double notation'' only on occasion for the benefit of those readers who are accustomed to it.

Star Notation
.............

The following notation specifies the storage size for a type:

     GENERIC-TYPE*N

GENERIC-TYPE must be a generic type---one of INTEGER, REAL, COMPLEX, LOGICAL, or CHARACTER. N must be one or more digits comprising a decimal integer number greater than zero.

Use the above form where a type name is valid.

The *N notation specifies that the amount of storage occupied by variables and array elements of that type is N times the storage occupied by a CHARACTER*1 variable.

This notation might indicate a different degree of precision and/or range for such variables and array elements, and the functions that return values of types using this notation. It does not limit the precision or range of values of that type in any particular way---use explicit code to do that.

Further, the GNU Fortran language requires no particular values for N to be supported by an implementation via the *N notation. g77 supports INTEGER*1 (as INTEGER(KIND=3)) on all systems, for example, but not all implementations are required to do so, and g77 is known to not support REAL*1 on most (or all) systems.

As a result, except for GENERIC-TYPE of CHARACTER, uses of this notation should be limited to isolated portions of a program that are intended to handle system-specific tasks and are expected to be non-portable.

(Standard FORTRAN 77 supports the *N notation for only CHARACTER, where it signifies not only the amount of storage occupied, but the number of characters in entities of that type. However, almost all Fortran compilers have supported this notation for generic types, though with a variety of meanings for N.)

Specifications of types using the *N notation always are interpreted as specifications of the appropriate types described in this document using the KIND=N notation, described below.

While use of this notation is popular, it doesn't serve well in the context of a widely portable dialect of Fortran, such as the GNU Fortran language.

For example, even on one particular machine, two or more popular Fortran compilers might well disagree on the size of a type declared INTEGER*2 or REAL*16. Certainly there is known to be disagreement over such things among Fortran compilers on different systems.

Further, this notation offers no elegant way to specify sizes that are not even multiples of the ``byte size'' typically designated by INTEGER*1. Use of ``absurd'' values (such as INTEGER*1000) would certainly be possible, but would perhaps be stretching the original intent of this notation beyond the breaking point in terms of widespread readability of documentation and code making use of it.

Therefore, this document uses ``star notation'' only on occasion for the benefit of those readers who are accustomed to it.

Kind Notation
.............

The following notation specifies the kind-type selector of a type:

     GENERIC-TYPE(KIND=N)

Use the above form where a type name is valid.

GENERIC-TYPE must be a generic type---one of INTEGER, REAL, COMPLEX, LOGICAL, or CHARACTER. N must be an integer initialization expression that is a positive, nonzero value.

Programmers are discouraged from writing these values directly into their code. Future versions of the GNU Fortran language will offer facilities that will make the writing of code portable to g77 and Fortran 90 implementations simpler.

However, writing code that ports to existing FORTRAN 77 implementations depends on avoiding the KIND= construct.

The KIND= construct is thus useful in the context of GNU Fortran for two reasons:

  * It provides a means to specify a type in a fashion that is portable across all GNU Fortran implementations (though not other FORTRAN 77 and Fortran 90 implementations).

  * It provides a sort of Rosetta stone for this document to use to concisely describe the types of various operations and operands.

The values of N in the GNU Fortran language are assigned using a scheme that:

  * Attempts to maximize the ability of readers of this document to quickly familiarize themselves with assignments for popular types

  * Provides a unique value for each specific desired meaning

  * Provides a means to automatically assign new values so they have a ``natural'' relationship to existing values, if appropriate, or, if no such relationship exists, will not interfere with future values assigned on the basis of such relationships

  * Avoids using values that are similar to values used in the existing, popular *N notation, to prevent readers from expecting that these implied correspondences work on all GNU Fortran implementations

The assignment system accomplishes this by assigning to each ``fundamental meaning'' of a specific type a unique prime number. Combinations of fundamental meanings---for example, a type that is two times the size of some other type---are assigned values of N that are the products of the values for those fundamental meanings.

A prime value of N is never given more than one fundamental meaning, to avoid situations where some code or system cannot reasonably provide those meanings in the form of a single type.

The values of N assigned so far are:

KIND=0
     This value is reserved for future use.

     The planned future use is for this value to designate, explicitly, context-sensitive kind-type selection. For example, the expression 1D0 * 0.1_0 would be equivalent to 1D0 * 0.1D0.

KIND=1
     This corresponds to the default types for REAL, INTEGER, LOGICAL, COMPLEX, and CHARACTER, as appropriate.

     These are the ``default'' types described in the Fortran 90 standard, though that standard does not assign any particular KIND= value to these types.

     (Typically, these are REAL*4, INTEGER*4, LOGICAL*4, and COMPLEX*8.)

KIND=2
     This corresponds to types that occupy twice as much storage as the default types. REAL(KIND=2) is DOUBLE PRECISION (typically REAL*8), COMPLEX(KIND=2) is DOUBLE COMPLEX (typically COMPLEX*16),

     These are the ``double precision'' types described in the Fortran 90 standard, though that standard does not assign any particular KIND= value to these types.

     N of 4 thus corresponds to types that occupy four times as much storage as the default types, N of 8 to types that occupy eight times as much storage, and so on.

     The INTEGER(KIND=2) and LOGICAL(KIND=2) types are not necessarily supported by every GNU Fortran implementation.

KIND=3
     This corresponds to types that occupy as much storage as the default CHARACTER type, which is the same effective type as CHARACTER(KIND=1) (making that type effectively the same as CHARACTER(KIND=3)).

     (Typically, these are INTEGER*1 and LOGICAL*1.)

     N of 6 thus corresponds to types that occupy twice as much storage as the N=3 types, N of 12 to types that occupy four times as much storage, and so on.

     These are not necessarily supported by every GNU Fortran implementation.

KIND=5
     This corresponds to types that occupy half the storage as the default (N=1) types.

     (Typically, these are INTEGER*2 and LOGICAL*2.)

     N of 25 thus corresponds to types that occupy one-quarter as much storage as the default types.

     These are not necessarily supported by every GNU Fortran implementation.

KIND=7
     This is valid only as INTEGER(KIND=7) and denotes the INTEGER type that has the smallest storage size that holds a pointer on the system.

     A pointer representable by this type is capable of uniquely addressing a CHARACTER*1 variable, array, array element, or substring.

     (Typically this is equivalent to INTEGER*4 or, on 64-bit systems, INTEGER*8. In a compatible C implementation, it typically would be the same size and semantics of the C type void *.)

Note that these are proposed correspondences and might change in future versions of g77---avoid writing code depending on them while g77, and therefore the GNU Fortran language it defines, is in beta testing.

Values not specified in the above list are reserved to future versions of the GNU Fortran language.

Implementation-dependent meanings will be assigned new, unique prime numbers so as to not interfere with other implementation-dependent meanings, and offer the possibility of increasing the portability of code depending on such types by offering support for them in other GNU Fortran implementations.

Other meanings that might be given unique values are:

  * Types that make use of only half their storage size for representing precision and range.

     For example, some compilers offer options that cause INTEGER types to occupy the amount of storage that would be needed for INTEGER(KIND=2) types, but the range remains that of INTEGER(KIND=1).

  * The IEEE single floating-point type.

  * Types with a specific bit pattern (endianness), such as the little-endian form of INTEGER(KIND=1). These could permit, conceptually, use of portable code and implementations on data files written by existing systems.

Future prime numbers should be given meanings in as incremental a fashion as possible, to allow for flexibility and expressiveness in combining types.

For example, instead of defining a prime number for little-endian IEEE doubles, one prime number might be assigned the meaning ``little-endian'', another the meaning ``IEEE double'', and the value of N for a little-endian IEEE double would thus naturally be the product of those two respective assigned values. (It could even be reasonable to have IEEE values result from the products of prime values denoting exponent and fraction sizes and meanings, hidden bit usage, availability and representations of special values such as subnormals, infinities, and Not-A-Numbers (NaNs), and so on.)

This assignment mechanism, while not inherently required for future versions of the GNU Fortran language, is worth using because it could ease management of the ``space'' of supported types much easier in the long run.

The above approach suggests a mechanism for specifying inheritance of intrinsic (built-in) types for an entire, widely portable product line. It is certainly reasonable that, unlike programmers of other languages offering inheritance mechanisms that employ verbose names for classes and subclasses, along with graphical browsers to elucidate the relationships, Fortran programmers would employ a mechanism that works by multiplying prime numbers together and finding the prime factors of such products.

Most of the advantages for the above scheme have been explained above. One disadvantage is that it could lead to the defining, by the GNU Fortran language, of some fairly large prime numbers. This could lead to the GNU Fortran language being declared ``munitions'' by the United States Department of Defense.

Constants
---------

(Corresponds to Section 4.2 of ANSI X3.9-1978 FORTRAN 77.)

A typeless constant has one of the following forms:

     'BINARY-DIGITS'B
     'OCTAL-DIGITS'O
     'HEXADECIMAL-DIGITS'Z
     'HEXADECIMAL-DIGITS'X

BINARY-DIGITS, OCTAL-DIGITS, and HEXADECIMAL-DIGITS are nonempty strings of characters in the set 01, 01234567, and 0123456789ABCDEFabcdef, respectively. (The value for A (and a) is 10, for B and b is 11, and so on.)

A prefix-radix constant, such as Z'ABCD', can optionally be treated as typeless.  See Options Controlling Fortran Dialect, for information on the -ftypeless-boz option.

Typeless constants have values that depend on the context in which they are used.

All other constants, called typed constants, are interpreted---converted to internal form---according to their inherent type. Thus, context is never a determining factor for the type, and hence the interpretation, of a typed constant. (All constants in the ANSI FORTRAN 77 language are typed constants.)

For example, 1 is always type INTEGER(KIND=1) in GNU Fortran (called default INTEGER in Fortran 90), 9.435784839284958 is always type REAL(KIND=1) (even if the additional precision specified is lost, and even when used in a REAL(KIND=2) context), 1E0 is always type REAL(KIND=2), and 1D0 is always type REAL(KIND=2).

Integer Type
------------

(Corresponds to Section 4.3 of ANSI X3.9-1978 FORTRAN 77.)

An integer constant also may have one of the following forms:

     B'BINARY-DIGITS'
     O'OCTAL-DIGITS'
     Z'HEXADECIMAL-DIGITS'
     X'HEXADECIMAL-DIGITS'

BINARY-DIGITS, OCTAL-DIGITS, and HEXADECIMAL-DIGITS are nonempty strings of characters in the set 01, 01234567, and 0123456789ABCDEFabcdef, respectively. (The value for A (and a) is 10, for B and b is 11, and so on.)

Character Type
--------------

(Corresponds to Section 4.8 of ANSI X3.9-1978 FORTRAN 77.)

A character constant may be delimited by a pair of double quotes (") instead of apostrophes. In this case, an apostrophe within the constant represents a single apostrophe, while a double quote is represented in the source text of the constant by two consecutive double quotes with no intervening spaces.

A character constant may be empty (have a length of zero).

A character constant may include a substring specification, The value of such a constant is the value of the substring---for example, the value of 'hello'(3:5) is the same as the value of 'llo'.

Expressions
===========

(The following information augments or overrides the information in Chapter 6 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 6 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

The %LOC() Construct
--------------------

     %LOC(ARG)

The %LOC() construct is an expression that yields the value of the location of its argument, ARG, in memory. The size of the type of the expression depends on the system---typically, it is equivalent to either INTEGER(KIND=1) or INTEGER(KIND=2), though it is actually type INTEGER(KIND=7).

The argument to %LOC() must be suitable as the left-hand side of an assignment statement. That is, it may not be a general expression involving operators such as addition, subtraction, and so on, nor may it be a constant.

Use of %LOC() is recommended only for code that is accessing facilities outside of GNU Fortran, such as operating system or windowing facilities. It is best to constrain such uses to isolated portions of a program---portions that deal specifically and exclusively with low-level, system-dependent facilities. Such portions might well provide a portable interface for use by the program as a whole, but are themselves not portable, and should be thoroughly tested each time they are rebuilt using a new compiler or version of a compiler.

Do not depend on %LOC() returning a pointer that can be safely used to define (change) the argument. While this might work in some circumstances, it is hard to predict whether it will continue to work when a program (that works using this unsafe behavior) is recompiled using different command-line options or a different version of g77.

Generally, %LOC() is safe when used as an argument to a procedure that makes use of the value of the corresponding dummy argument only during its activation, and only when such use is restricted to referencing (reading) the value of the argument to %LOC().

Implementation Note: Currently, g77 passes arguments (those not passed using a construct such as %VAL()) by reference or descriptor, depending on the type of the actual argument. Thus, given INTEGER I, CALL FOO(I) would seem to mean the same thing as CALL FOO(%VAL(%LOC(I))), and in fact might compile to identical code.

However, CALL FOO(%VAL(%LOC(I))) emphatically means ``pass, by value, the address of I in memory''. While CALL FOO(I) might use that same approach in a particular version of g77, another version or compiler might choose a different implementation, such as copy-in/copy-out, to effect the desired behavior---and which will therefore not necessarily compile to the same code as would CALL FOO(%VAL(%LOC(I))) using the same version or compiler.

See Debugging and Interfacing, for detailed information on how this particular version of g77 implements various constructs.

Specification Statements
========================

(The following information augments or overrides the information in Chapter 8 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 8 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

NAMELIST Statement
------------------

The NAMELIST statement, and related I/O constructs, are supported by the GNU Fortran language in essentially the same way as they are by f2c.

This follows Fortran 90 with the restriction that on NAMELIST input, subscripts must have the form

     SUBSCRIPT [ : SUBSCRIPT [ : STRIDE]]

i.e.

     &xx x(1:3,8:10:2)=1,2,3,4,5,6/

is allowed, but not, say,

     &xx x(:3,8::2)=1,2,3,4,5,6/

As an extension of the Fortran 90 form, $ and $END may be used in place of & and / in NAMELIST input, so that

     $&xx x(1:3,8:10:2)=1,2,3,4,5,6 $end

could be used instead of the example above.

DOUBLE COMPLEX Statement
------------------------

DOUBLE COMPLEX is a type-statement (and type) that specifies the type COMPLEX(KIND=2) in GNU Fortran.

Control Statements
==================

(The following information augments or overrides the information in Chapter 11 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 11 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

DO WHILE
--------

The DO WHILE statement, a feature of both the MIL-STD 1753 and Fortran 90 standards, is provided by the GNU Fortran language. The Fortran 90 ``do forever'' statement comprising just DO is also supported.

END DO
------

The END DO statement is provided by the GNU Fortran language.

This statement is used in one of two ways:

  * The Fortran 90 meaning, in which it specifies the termination point of a single DO loop started with a DO statement that specifies no termination label.

  * The MIL-STD 1753 meaning, in which it specifies the termination point of one or more DO loops, all of which start with a DO statement that specify the label defined for the END DO statement.

     This kind of END DO statement is merely a synonym for CONTINUE, except it is permitted only when the statement is labeled and a target of one or more labeled DO loops.

     It is expected that this use of END DO will be removed from the GNU Fortran language in the future, though it is likely that it will long be supported by g77 as a dialect form.

Construct Names
---------------

The GNU Fortran language supports construct names as defined by the Fortran 90 standard. These names are local to the program unit and are defined as follows:

     CONSTRUCT-NAME: BLOCK-STATEMENT

Here, CONSTRUCT-NAME is the construct name itself; its definition is connoted by the single colon (:); and BLOCK-STATEMENT is an IF, DO, or SELECT CASE statement that begins a block.

A block that is given a construct name must also specify the same construct name in its termination statement:

     END BLOCK CONSTRUCT-NAME

Here, BLOCK must be IF, DO, or SELECT, as appropriate.

The CYCLE and EXIT Statements
-----------------------------

The CYCLE and EXIT statements specify that the remaining statements in the current iteration of a particular active (enclosing) DO loop are to be skipped.

CYCLE specifies that these statements are skipped, but the END DO statement that marks the end of the DO loop be executed---that is, the next iteration, if any, is to be started. If the statement marking the end of the DO loop is not END DO---in other words, if the loop is not a block DO---the CYCLE statement does not execute that statement, but does start the next iteration (if any).

EXIT specifies that the loop specified by the DO construct is terminated.

The DO loop affected by CYCLE and EXIT is the innermost enclosing DO loop when the following forms are used:

     CYCLE
     EXIT

Otherwise, the following forms specify the construct name of the pertinent DO loop:

     CYCLE CONSTRUCT-NAME
     EXIT CONSTRUCT-NAME

CYCLE and EXIT can be viewed as glorified GO TO statements. However, they cannot be easily thought of as GO TO statements in obscure cases involving FORTRAN 77 loops. For example:

           DO 10 I = 1, 5
           DO 10 J = 1, 5
              IF (J .EQ. 5) EXIT
           DO 10 K = 1, 5
              IF (K .EQ. 3) CYCLE
     10    PRINT *, 'I=', I, ' J=', J, ' K=', K
     20    CONTINUE

In particular, neither the EXIT nor CYCLE statements above are equivalent to a GO TO statement to either label 10 or 20.

To understand the effect of CYCLE and EXIT in the above fragment, it is helpful to first translate it to its equivalent using only block DO loops:

           DO I = 1, 5
              DO J = 1, 5
                 IF (J .EQ. 5) EXIT
                 DO K = 1, 5
                    IF (K .EQ. 3) CYCLE
     10             PRINT *, 'I=', I, ' J=', J, ' K=', K
                 END DO
              END DO
           END DO
     20    CONTINUE

Adding new labels allows translation of CYCLE and EXIT to GO TO so they may be more easily understood by programmers accustomed to FORTRAN coding:

           DO I = 1, 5
              DO J = 1, 5
                 IF (J .EQ. 5) GOTO 18
                 DO K = 1, 5
                    IF (K .EQ. 3) GO TO 12
     10             PRINT *, 'I=', I, ' J=', J, ' K=', K
     12          END DO
              END DO
     18    END DO
     20    CONTINUE

Thus, the CYCLE statement in the innermost loop skips over the PRINT statement as it begins the next iteration of the loop, while the EXIT statement in the middle loop ends that loop but not the outermost loop.

Functions and Subroutines
=========================

(The following information augments or overrides the information in Chapter 15 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 15 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

The %VAL() Construct
--------------------

     %VAL(ARG)

The %VAL() construct specifies that an argument, ARG, is to be passed by value, instead of by reference or descriptor.

%VAL() is restricted to actual arguments in invocations of external procedures.

Use of %VAL() is recommended only for code that is accessing facilities outside of GNU Fortran, such as operating system or windowing facilities. It is best to constrain such uses to isolated portions of a program---portions the deal specifically and exclusively with low-level, system-dependent facilities. Such portions might well provide a portable interface for use by the program as a whole, but are themselves not portable, and should be thoroughly tested each time they are rebuilt using a new compiler or version of a compiler.

Implementation Note: Currently, g77 passes all arguments either by reference or by descriptor.

Thus, use of %VAL() tends to be restricted to cases where the called procedure is written in a language other than Fortran that supports call-by-value semantics. (C is an example of such a language.)

See Procedures (SUBROUTINE and FUNCTION), for detailed information on how this particular version of g77 passes arguments to procedures.

The %REF() Construct
--------------------

     %REF(ARG)

The %REF() construct specifies that an argument, ARG, is to be passed by reference, instead of by value or descriptor.

%REF() is restricted to actual arguments in invocations of external procedures.

Use of %REF() is recommended only for code that is accessing facilities outside of GNU Fortran, such as operating system or windowing facilities. It is best to constrain such uses to isolated portions of a program---portions the deal specifically and exclusively with low-level, system-dependent facilities. Such portions might well provide a portable interface for use by the program as a whole, but are themselves not portable, and should be thoroughly tested each time they are rebuilt using a new compiler or version of a compiler.

Do not depend on %REF() supplying a pointer to the procedure being invoked. While that is a likely implementation choice, other implementation choices are available that preserve Fortran pass-by-reference semantics without passing a pointer to the argument, ARG. (For example, a copy-in/copy-out implementation.)

Implementation Note: Currently, g77 passes all arguments (other than variables and arrays of type CHARACTER) by reference. Future versions of, or dialects supported by, g77 might not pass CHARACTER functions by reference.

Thus, use of %REF() tends to be restricted to cases where ARG is type CHARACTER but the called procedure accesses it via a means other than the method used for Fortran CHARACTER arguments.

See Procedures (SUBROUTINE and FUNCTION), for detailed information on how this particular version of g77 passes arguments to procedures.

The %DESCR() Construct
----------------------

     %DESCR(ARG)

The %DESCR() construct specifies that an argument, ARG, is to be passed by descriptor, instead of by value or reference.

%DESCR() is restricted to actual arguments in invocations of external procedures.

Use of %DESCR() is recommended only for code that is accessing facilities outside of GNU Fortran, such as operating system or windowing facilities. It is best to constrain such uses to isolated portions of a program---portions the deal specifically and exclusively with low-level, system-dependent facilities. Such portions might well provide a portable interface for use by the program as a whole, but are themselves not portable, and should be thoroughly tested each time they are rebuilt using a new compiler or version of a compiler.

Do not depend on %DESCR() supplying a pointer and/or a length passed by value to the procedure being invoked. While that is a likely implementation choice, other implementation choices are available that preserve the pass-by-reference semantics without passing a pointer to the argument, ARG. (For example, a copy-in/copy-out implementation.) And, future versions of g77 might change the way descriptors are implemented, such as passing a single argument pointing to a record containing the pointer/length information instead of passing that same information via two arguments as it currently does.

Implementation Note: Currently, g77 passes all variables and arrays of type CHARACTER by descriptor. Future versions of, or dialects supported by, g77 might pass CHARACTER functions by descriptor as well.

Thus, use of %DESCR() tends to be restricted to cases where ARG is not type CHARACTER but the called procedure accesses it via a means similar to the method used for Fortran CHARACTER arguments.

See Procedures (SUBROUTINE and FUNCTION), for detailed information on how this particular version of g77 passes arguments to procedures.

Generics and Specifics
----------------------

The ANSI FORTRAN 77 language defines generic and specific intrinsics. In short, the distinctions are:

  * Specific intrinsics have specific types for their arguments and a specific return type.

  * Generic intrinsics are treated, on a case-by-case basis in the program's source code, as one of several possible specific intrinsics.

     Typically, a generic intrinsic has a return type that is determined by the type of one or more of its arguments.

The GNU Fortran language generalizes these concepts somewhat, especially by providing intrinsic subroutines and generic intrinsics that are treated as either a specific intrinsic subroutine or a specific intrinsic function (e.g. SECOND).

However, GNU Fortran avoids generalizing this concept to the point where existing code would be accepted as meaning something possibly different than what was intended.

For example, ABS is a generic intrinsic, so all working code written using ABS of an INTEGER argument expects an INTEGER return value. Similarly, all such code expects that ABS of an INTEGER*2 argument returns an INTEGER*2 return value.

Yet, IABS is a specific intrinsic that accepts only an INTEGER(KIND=1) argument. Code that passes something other than an INTEGER(KIND=1) argument to IABS is not valid GNU Fortran code, because it is not clear what the author intended.

For example, if J is INTEGER(KIND=6), IABS(J) is not defined by the GNU Fortran language, because the programmer might have used that construct to mean any of the following, subtly different, things:

  * Convert J to INTEGER(KIND=1) first (as if IABS(INT(J)) had been written).

  * Convert the result of the intrinsic to INTEGER(KIND=1) (as if INT(ABS(J)) had been written).

  * No conversion (as if ABS(J) had been written).

The distinctions matter especially when types and values wider than INTEGER(KIND=1) (such as INTEGER(KIND=2)), or when operations performing more ``arithmetic'' than absolute-value, are involved.

The following sample program is not a valid GNU Fortran program, but might be accepted by other compilers. If so, the output is likely to be revealing in terms of how a given compiler treats intrinsics (that normally are specific) when they are given arguments that do not conform to their stated requirements:

           PROGRAM JCB002
     C Version 1:
     C Modified 1999-02-15 (Burley) to delete my email address.
     C Modified 1997-05-21 (Burley) to accommodate compilers that implement
     C INT(I1-I2) as INT(I1)-INT(I2) given INTEGER*2 I1,I2.
     C
     C Version 0:
     C Written by James Craig Burley 1997-02-20.
     C
     C Purpose:
     C Determine how compilers handle non-standard IDIM
     C on INTEGER*2 operands, which presumably can be
     C extrapolated into understanding how the compiler
     C generally treats specific intrinsics that are passed
     C arguments not of the correct types.
     C
     C If your compiler implements INTEGER*2 and INTEGER
     C as the same type, change all INTEGER*2 below to
     C INTEGER*1.
     C
           INTEGER*2 I0, I4
           INTEGER I1, I2, I3
           INTEGER*2 ISMALL, ILARGE
           INTEGER*2 ITOOLG, ITWO
           INTEGER*2 ITMP
           LOGICAL L2, L3, L4
     C
     C Find smallest INTEGER*2 number.
     C
           ISMALL=0
      10   I0 = ISMALL-1
           IF ((I0 .GE. ISMALL) .OR. (I0+1 .NE. ISMALL)) GOTO 20
           ISMALL = I0
           GOTO 10
      20   CONTINUE
     C
     C Find largest INTEGER*2 number.
     C
           ILARGE=0
      30   I0 = ILARGE+1
           IF ((I0 .LE. ILARGE) .OR. (I0-1 .NE. ILARGE)) GOTO 40
           ILARGE = I0
           GOTO 30
      40   CONTINUE
     C
     C Multiplying by two adds stress to the situation.
     C
           ITWO = 2
     C
     C Need a number that, added to -2, is too wide to fit in I*2.
     C
           ITOOLG = ISMALL
     C
     C Use IDIM the straightforward way.
     C
           I1 = IDIM (ILARGE, ISMALL) * ITWO + ITOOLG
     C
     C Calculate result for first interpretation.
     C
           I2 = (INT (ILARGE) - INT (ISMALL)) * ITWO + ITOOLG
     C
     C Calculate result for second interpretation.
     C
           ITMP = ILARGE - ISMALL
           I3 = (INT (ITMP)) * ITWO + ITOOLG
     C
     C Calculate result for third interpretation.
     C
           I4 = (ILARGE - ISMALL) * ITWO + ITOOLG
     C
     C Print results.
     C
           PRINT *, 'ILARGE=', ILARGE
           PRINT *, 'ITWO=', ITWO
           PRINT *, 'ITOOLG=', ITOOLG
           PRINT *, 'ISMALL=', ISMALL
           PRINT *, 'I1=', I1
           PRINT *, 'I2=', I2
           PRINT *, 'I3=', I3
           PRINT *, 'I4=', I4
           PRINT *
           L2 = (I1 .EQ. I2)
           L3 = (I1 .EQ. I3)
           L4 = (I1 .EQ. I4)
           IF (L2 .AND. .NOT.L3 .AND. .NOT.L4) THEN
              PRINT *, 'Interp 1: IDIM(I*2,I*2) => IDIM(INT(I*2),INT(I*2))'
              STOP
           END IF
           IF (L3 .AND. .NOT.L2 .AND. .NOT.L4) THEN
              PRINT *, 'Interp 2: IDIM(I*2,I*2) => INT(DIM(I*2,I*2))'
              STOP
           END IF
           IF (L4 .AND. .NOT.L2 .AND. .NOT.L3) THEN
              PRINT *, 'Interp 3: IDIM(I*2,I*2) => DIM(I*2,I*2)'
              STOP
           END IF
           PRINT *, 'Results need careful analysis.'
           END

No future version of the GNU Fortran language will likely permit specific intrinsic invocations with wrong-typed arguments (such as IDIM in the above example), since it has been determined that disagreements exist among many production compilers on the interpretation of such invocations. These disagreements strongly suggest that Fortran programmers, and certainly existing Fortran programs, disagree about the meaning of such invocations.

The first version of JCB002 didn't accommodate some compilers' treatment of INT(I1-I2) where I1 and I2 are INTEGER*2. In such a case, these compilers apparently convert both operands to INTEGER*4 and then do an INTEGER*4 subtraction, instead of doing an INTEGER*2 subtraction on the original values in I1 and I2.

However, the results of the careful analyses done on the outputs of programs compiled by these various compilers show that they all implement either Interp 1 or Interp 2 above.

Specifically, it is believed that the new version of JCB002 above will confirm that:

  * Digital Semiconductor (``DEC'') Alpha OSF/1, HP-UX 10.0.1, AIX 3.2.5 f77 compilers all implement Interp 1.

  * IRIX 5.3 f77 compiler implements Interp 2.

  * Solaris 2.5, SunOS 4.1.3, DECstation ULTRIX 4.3, and IRIX 6.1 f77 compilers all implement Interp 3.

If you get different results than the above for the stated compilers, or have results for other compilers that might be worth adding to the above list, please let us know the details (compiler product, version, machine, results, and so on).

REAL() and AIMAG() of Complex
-----------------------------

The GNU Fortran language disallows REAL(EXPR) and AIMAG(EXPR), where EXPR is any COMPLEX type other than COMPLEX(KIND=1), except when they are used in the following way:

     REAL(REAL(EXPR))
     REAL(AIMAG(EXPR))

The above forms explicitly specify that the desired effect is to convert the real or imaginary part of EXPR, which might be some REAL type other than REAL(KIND=1), to type REAL(KIND=1), and have that serve as the value of the expression.

The GNU Fortran language offers clearly named intrinsics to extract the real and imaginary parts of a complex entity without any conversion:

     REALPART(EXPR)
     IMAGPART(EXPR)

To express the above using typical extended FORTRAN 77, use the following constructs (when EXPR is COMPLEX(KIND=2)):

     DBLE(EXPR)
     DIMAG(EXPR)

The FORTRAN 77 language offers no way to explicitly specify the real and imaginary parts of a complex expression of arbitrary type, apparently as a result of requiring support for only one COMPLEX type (COMPLEX(KIND=1)). The concepts of converting an expression to type REAL(KIND=1) and of extracting the real part of a complex expression were thus ``smooshed'' by FORTRAN 77 into a single intrinsic, since they happened to have the exact same effect in that language (due to having only one COMPLEX type).

Note: When -ff90 is in effect, g77 treats REAL(EXPR), where EXPR is of type COMPLEX, as REALPART(EXPR), whereas with -fugly-complex -fno-f90 in effect, it is treated as REAL(REALPART(EXPR)).

See Ugly Complex Part Extraction, for more information.

CMPLX() of DOUBLE PRECISION
---------------------------

In accordance with Fortran 90 and at least some (perhaps all) other compilers, the GNU Fortran language defines CMPLX() as always returning a result that is type COMPLEX(KIND=1).

This means CMPLX(D1,D2), where D1 and D2 are REAL(KIND=2) (DOUBLE PRECISION), is treated as:

     CMPLX(SNGL(D1), SNGL(D2))

(It was necessary for Fortran 90 to specify this behavior for DOUBLE PRECISION arguments, since that is the behavior mandated by FORTRAN 77.)

The GNU Fortran language also provides the DCMPLX() intrinsic, which is provided by some FORTRAN 77 compilers to construct a DOUBLE COMPLEX entity from of DOUBLE PRECISION operands. However, this solution does not scale well when more COMPLEX types (having various precisions and ranges) are offered by Fortran implementations.

Fortran 90 extends the CMPLX() intrinsic by adding an extra argument used to specify the desired kind of complex result. However, this solution is somewhat awkward to use, and g77 currently does not support it.

The GNU Fortran language provides a simple way to build a complex value out of two numbers, with the precise type of the value determined by the types of the two numbers (via the usual type-promotion mechanism):

     COMPLEX(REAL, IMAG)

When REAL and IMAG are the same REAL types, COMPLEX() performs no conversion other than to put them together to form a complex result of the same (complex version of real) type.

See Complex Intrinsic, for more information.

MIL-STD 1753 Support
--------------------

The GNU Fortran language includes the MIL-STD 1753 intrinsics BTEST, IAND, IBCLR, IBITS, IBSET, IEOR, IOR, ISHFT, ISHFTC, MVBITS, and NOT.

f77/f2c Intrinsics
------------------

The bit-manipulation intrinsics supported by traditional f77 and by f2c are available in the GNU Fortran language. These include AND, LSHIFT, OR, RSHIFT, and XOR.

Also supported are the intrinsics CDABS, CDCOS, CDEXP, CDLOG, CDSIN, CDSQRT, DCMPLX, DCONJG, DFLOAT, DIMAG, DREAL, and IMAG, ZABS, ZCOS, ZEXP, ZLOG, ZSIN, and ZSQRT.

Table of Intrinsic Functions
----------------------------

(Corresponds to Section 15.10 of ANSI X3.9-1978 FORTRAN 77.)

The GNU Fortran language adds various functions, subroutines, types, and arguments to the set of intrinsic functions in ANSI FORTRAN 77. The complete set of intrinsics supported by the GNU Fortran language is described below.

Note that a name is not treated as that of an intrinsic if it is specified in an EXTERNAL statement in the same program unit; if a command-line option is used to disable the groups to which the intrinsic belongs; or if the intrinsic is not named in an INTRINSIC statement and a command-line option is used to hide the groups to which the intrinsic belongs.

So, it is recommended that any reference in a program unit to an intrinsic procedure that is not a standard FORTRAN 77 intrinsic be accompanied by an appropriate INTRINSIC statement in that program unit. This sort of defensive programming makes it more likely that an implementation will issue a diagnostic rather than generate incorrect code for such a reference.

The terminology used below is based on that of the Fortran 90 standard, so that the text may be more concise and accurate:

  * OPTIONAL means the argument may be omitted.

  * A-1, A-2, ..., A-n means more than one argument (generally named A) may be specified.

  * scalar means the argument must not be an array (must be a variable or array element, or perhaps a constant if expressions are permitted).

  * DIMENSION(4) means the argument must be an array having 4 elements.

  * INTENT(IN) means the argument must be an expression (such as a constant or a variable that is defined upon invocation of the intrinsic).

  * INTENT(OUT) means the argument must be definable by the invocation of the intrinsic (that is, must not be a constant nor an expression involving operators other than array reference and substring reference).

  * INTENT(INOUT) means the argument must be defined prior to, and definable by, invocation of the intrinsic (a combination of the requirements of INTENT(IN) and INTENT(OUT).

  * See Kind Notation, for an explanation of KIND.

(Note that the empty lines appearing in the menu below are not intentional---they result from a bug in the GNU makeinfo program...a program that, if it did not exist, would leave this document in far worse shape!)

     [file intdoc.texi not included]

Scope and Classes of Symbolic Names
===================================

(The following information augments or overrides the information in Chapter 18 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran language. Chapter 18 of that document otherwise serves as the basis for the relevant aspects of GNU Fortran.)

Underscores in Symbol Names
---------------------------

Underscores (_) are accepted in symbol names after the first character (which must be a letter).

I/O
===

A dollar sign at the end of an output format specification suppresses the newline at the end of the output.

Edit descriptors in FORMAT statements may contain compile-time INTEGER constant expressions in angle brackets, such as

     10    FORMAT (I<WIDTH>)

The OPEN specifier NAME= is equivalent to FILE=.

These Fortran 90 features are supported:

  * The O and Z edit descriptors are supported for I/O of integers in octal and hexadecimal formats, respectively.

  * The FILE= specifier may be omitted in an OPEN statement if STATUS='SCRATCH' is supplied.  The STATUS='REPLACE' specifier is supported.

Fortran 90 Features
===================

For convenience this section collects a list (probably incomplete) of the Fortran 90 features supported by the GNU Fortran language, even if they are documented elsewhere. See Characters, Lines, and Execution Sequence, for information on additional fixed source form lexical issues. Further, the free source form is supported through the -ffree-form option. Other Fortran 90 features can be turned on by the -ff90 option; see Fortran 90. For information on the Fortran 90 intrinsics available, see Table of Intrinsic Functions.

Automatic arrays in procedures

Character assignments
     In character assignments, the variable being assigned may occur on the right hand side of the assignment.

Character strings
     Strings may have zero length and substrings of character constants are permitted.  Character constants may be enclosed in double quotes (") as well as single quotes.  See Character Type.

Construct names
     (Symbolic tags on blocks.)  See Construct Names.

CYCLE and EXIT
     See The CYCLE and EXIT Statements.

DOUBLE COMPLEX
     See DOUBLE COMPLEX Statement.

DO WHILE
     See DO WHILE.

END decoration
     See Statements.

END DO
     See END DO.

KIND

IMPLICIT NONE

INCLUDE statements
     See INCLUDE.

List-directed and namelist I/O on internal files

Binary, octal and hexadecimal constants
     These are supported more generally than required by Fortran 90. See Integer Type.

O and Z edit descriptors

NAMELIST
     See NAMELIST.

OPEN specifiers
     STATUS='REPLACE' is supported. The FILE= specifier may be omitted in an OPEN statement if STATUS='SCRATCH' is supplied.

FORMAT edit descriptors
     The Z edit descriptor is supported.

Relational operators
     The operators <, <=, ==, /=, > and >= may be used instead of .LT., .LE., .EQ., .NE., .GT. and .GE. respectively.

SELECT CASE
     Not fully implemented. See SELECT CASE on CHARACTER Type.

Specification statements
     A limited subset of the Fortran 90 syntax and semantics for variable declarations is supported, including KIND.  See Kind Notation. (KIND is of limited usefulness in the absence of the KIND-related intrinsics, since these intrinsics permit writing more widely portable code.)  An example of supported KIND usage is:

          INTEGER (KIND=1) :: FOO=1, BAR=2
          CHARACTER (LEN=3) FOO

     PARAMETER and DIMENSION attributes aren't supported.

Other Dialects
**************

GNU Fortran supports a variety of features that are not considered part of the GNU Fortran language itself, but are representative of various dialects of Fortran that g77 supports in whole or in part.

Any of the features listed below might be disallowed by g77 unless some command-line option is specified. Currently, some of the features are accepted using the default invocation of g77, but that might change in the future.

Note: This portion of the documentation definitely needs a lot of work!

Source Form
===========

GNU Fortran accepts programs written in either fixed form or free form.

Fixed form corresponds to ANSI FORTRAN 77 (plus popular extensions, such as allowing tabs) and Fortran 90's fixed form.

Free form corresponds to Fortran 90's free form (though possibly not entirely up-to-date, and without complaining about some things that for which Fortran 90 requires diagnostics, such as the spaces in the constant in R = 3 . 1).

The way a Fortran compiler views source files depends entirely on the implementation choices made for the compiler, since those choices are explicitly left to the implementation by the published Fortran standards. GNU Fortran currently tries to be somewhat like a few popular compilers (f2c, Digital (``DEC'') Fortran, and so on).

This section describes how g77 interprets source lines.

Carriage Returns
----------------

Carriage returns (\r) in source lines are ignored. This is somewhat different from f2c, which seems to treat them as spaces outside character/Hollerith constants, and encodes them as \r inside such constants.

Tabs
----

A source line with a TAB character anywhere in it is treated as entirely significant---however long it is---instead of ending in column 72 (for fixed-form source) or 132 (for free-form source). This also is different from f2c, which encodes tabs as \t (the ASCII TAB character) inside character and Hollerith constants, but nevertheless seems to treat the column position as if it had been affected by the canonical tab positioning.

g77 effectively translates tabs to the appropriate number of spaces (a la the default for the UNIX expand command) before doing any other processing, other than (currently) noting whether a tab was found on a line and using this information to decide how to interpret the length of the line and continued constants.

Short Lines
-----------

Source lines shorter than the applicable fixed-form length are treated as if they were padded with spaces to that length. (None of this is relevant to source files written in free form.)

This affects only continued character and Hollerith constants, and is a different interpretation than provided by some other popular compilers (although a bit more consistent with the traditional punched-card basis of Fortran and the way the Fortran standard expressed fixed source form).

g77 might someday offer an option to warn about cases where differences might be seen as a result of this treatment, and perhaps an option to specify the alternate behavior as well.

Note that this padding cannot apply to lines that are effectively of infinite length---such lines are specified using command-line options like -ffixed-line-length-none, for example.

Long Lines
----------

Source lines longer than the applicable length are truncated to that length. Currently, g77 does not warn if the truncated characters are not spaces, to accommodate existing code written for systems that treated truncated text as commentary (especially in columns 73 through 80).

See Options Controlling Fortran Dialect, for information on the -ffixed-line-length-N option, which can be used to set the line length applicable to fixed-form source files.

Ampersand Continuation Line
---------------------------

A & in column 1 of fixed-form source denotes an arbitrary-length continuation line, imitating the behavior of f2c.

Trailing Comment
================

g77 supports use of /* to start a trailing comment. In the GNU Fortran language, ! is used for this purpose.

/* is not in the GNU Fortran language because the use of /* in a program might suggest to some readers that a block, not trailing, comment is started (and thus ended by */, not end of line), since that is the meaning of /* in C.

Also, such readers might think they can use // to start a trailing comment as an alternative to /*, but // already denotes concatenation, and such a ``comment'' might actually result in a program that compiles without error (though it would likely behave incorrectly).

Debug Line
==========

Use of D or d as the first character (column 1) of a source line denotes a debug line.

In turn, a debug line is treated as either a comment line or a normal line, depending on whether debug lines are enabled.

When treated as a comment line, a line beginning with D or d is treated as if it the first character was C or c, respectively. When treated as a normal line, such a line is treated as if the first character was SPC (space).

(Currently, g77 provides no means for treating debug lines as normal lines.)

Dollar Signs in Symbol Names
============================

Dollar signs ($) are allowed in symbol names (after the first character) when the -fdollar-ok option is specified.

Case Sensitivity
================

GNU Fortran offers the programmer way too much flexibility in deciding how source files are to be treated vis-a-vis uppercase and lowercase characters. There are 66 useful settings that affect case sensitivity, plus 10 settings that are nearly useless, with the remaining 116 settings being either redundant or useless.

None of these settings have any effect on the contents of comments (the text after a c or C in Column 1, for example) or of character or Hollerith constants. Note that things like the E in the statement CALL FOO(3.2E10) and the TO in ASSIGN 10 TO LAB are considered built-in keywords, and so are affected by these settings.

Low-level switches are identified in this section as follows:

  A Source Case Conversion:

       0 Preserve (see Note 1)

       1 Convert to Upper Case

       2 Convert to Lower Case

  B Built-in Keyword Matching:

       0 Match Any Case (per-character basis)

       1 Match Upper Case Only

       2 Match Lower Case Only

       3 Match InitialCaps Only (see tables for spellings)

  C Built-in Intrinsic Matching:

       0 Match Any Case (per-character basis)

       1 Match Upper Case Only

       2 Match Lower Case Only

       3 Match InitialCaps Only (see tables for spellings)

  D User-defined Symbol Possibilities (warnings only):

       0 Allow Any Case (per-character basis)

       1 Allow Upper Case Only

       2 Allow Lower Case Only

       3 Allow InitialCaps Only (see Note 2)

Note 1: g77 eventually will support NAMELIST in a manner that is consistent with these source switches---in the sense that input will be expected to meet the same requirements as source code in terms of matching symbol names and keywords (for the exponent letters).

Currently, however, NAMELIST is supported by libg2c, which uppercases NAMELIST input and symbol names for matching. This means not only that NAMELIST output currently shows symbol (and keyword) names in uppercase even if lower-case source conversion (option A2) is selected, but that NAMELIST cannot be adequately supported when source case preservation (option A0) is selected.

If A0 is selected, a warning message will be output for each NAMELIST statement to this effect. The behavior of the program is undefined at run time if two or more symbol names appear in a given NAMELIST such that the names are identical when converted to upper case (e.g. NAMELIST /X/ VAR, Var, var). For complete and total elegance, perhaps there should be a warning when option A2 is selected, since the output of NAMELIST is currently in uppercase but will someday be lowercase (when a libg77 is written), but that seems to be overkill for a product in beta test.

Note 2: Rules for InitialCaps names are:

  - Must be a single uppercase letter, or

  - Must start with an uppercase letter and contain at least one lowercase letter.

So A, Ab, ABc, AbC, and Abc are valid InitialCaps names, but AB, A2, and ABC are not. Note that most, but not all, built-in names meet these requirements---the exceptions are some of the two-letter format specifiers, such as BN and BZ.

Here are the names of the corresponding command-line options:

     A0: -fsource-case-preserve
     A1: -fsource-case-upper
     A2: -fsource-case-lower

     B0: -fmatch-case-any
     B1: -fmatch-case-upper
     B2: -fmatch-case-lower
     B3: -fmatch-case-initcap

     C0: -fintrin-case-any
     C1: -fintrin-case-upper
     C2: -fintrin-case-lower
     C3: -fintrin-case-initcap

     D0: -fsymbol-case-any
     D1: -fsymbol-case-upper
     D2: -fsymbol-case-lower
     D3: -fsymbol-case-initcap

Useful combinations of the above settings, along with abbreviated option names that set some of these combinations all at once:

      1: A0--  B0---  C0---  D0---    -fcase-preserve
      2: A0--  B0---  C0---  D-1--
      3: A0--  B0---  C0---  D--2-
      4: A0--  B0---  C0---  D---3
      5: A0--  B0---  C-1--  D0---
      6: A0--  B0---  C-1--  D-1--
      7: A0--  B0---  C-1--  D--2-
      8: A0--  B0---  C-1--  D---3
      9: A0--  B0---  C--2-  D0---
     10: A0--  B0---  C--2-  D-1--
     11: A0--  B0---  C--2-  D--2-
     12: A0--  B0---  C--2-  D---3
     13: A0--  B0---  C---3  D0---
     14: A0--  B0---  C---3  D-1--
     15: A0--  B0---  C---3  D--2-
     16: A0--  B0---  C---3  D---3
     17: A0--  B-1--  C0---  D0---
     18: A0--  B-1--  C0---  D-1--
     19: A0--  B-1--  C0---  D--2-
     20: A0--  B-1--  C0---  D---3
     21: A0--  B-1--  C-1--  D0---
     22: A0--  B-1--  C-1--  D-1--    -fcase-strict-upper
     23: A0--  B-1--  C-1--  D--2-
     24: A0--  B-1--  C-1--  D---3
     25: A0--  B-1--  C--2-  D0---
     26: A0--  B-1--  C--2-  D-1--
     27: A0--  B-1--  C--2-  D--2-
     28: A0--  B-1--  C--2-  D---3
     29: A0--  B-1--  C---3  D0---
     30: A0--  B-1--  C---3  D-1--
     31: A0--  B-1--  C---3  D--2-
     32: A0--  B-1--  C---3  D---3
     33: A0--  B--2-  C0---  D0---
     34: A0--  B--2-  C0---  D-1--
     35: A0--  B--2-  C0---  D--2-
     36: A0--  B--2-  C0---  D---3
     37: A0--  B--2-  C-1--  D0---
     38: A0--  B--2-  C-1--  D-1--
     39: A0--  B--2-  C-1--  D--2-
     40: A0--  B--2-  C-1--  D---3
     41: A0--  B--2-  C--2-  D0---
     42: A0--  B--2-  C--2-  D-1--
     43: A0--  B--2-  C--2-  D--2-    -fcase-strict-lower
     44: A0--  B--2-  C--2-  D---3
     45: A0--  B--2-  C---3  D0---
     46: A0--  B--2-  C---3  D-1--
     47: A0--  B--2-  C---3  D--2-
     48: A0--  B--2-  C---3  D---3
     49: A0--  B---3  C0---  D0---
     50: A0--  B---3  C0---  D-1--
     51: A0--  B---3  C0---  D--2-
     52: A0--  B---3  C0---  D---3
     53: A0--  B---3  C-1--  D0---
     54: A0--  B---3  C-1--  D-1--
     55: A0--  B---3  C-1--  D--2-
     56: A0--  B---3  C-1--  D---3
     57: A0--  B---3  C--2-  D0---
     58: A0--  B---3  C--2-  D-1--
     59: A0--  B---3  C--2-  D--2-
     60: A0--  B---3  C--2-  D---3
     61: A0--  B---3  C---3  D0---
     62: A0--  B---3  C---3  D-1--
     63: A0--  B---3  C---3  D--2-
     64: A0--  B---3  C---3  D---3    -fcase-initcap
     65: A-1-  B01--  C01--  D01--    -fcase-upper
     66: A--2  B0-2-  C0-2-  D0-2-    -fcase-lower

Number 22 is the ``strict'' ANSI FORTRAN 77 model wherein all input (except comments, character constants, and Hollerith strings) must be entered in uppercase. Use -fcase-strict-upper to specify this combination.

Number 43 is like Number 22 except all input must be lowercase.  Use -fcase-strict-lower to specify this combination.

Number 65 is the ``classic'' ANSI FORTRAN 77 model as implemented on many non-UNIX machines whereby all the source is translated to uppercase. Use -fcase-upper to specify this combination.

Number 66 is the ``canonical'' UNIX model whereby all the source is translated to lowercase. Use -fcase-lower to specify this combination.

There are a few nearly useless combinations:

     67: A-1-  B01--  C01--  D--2-
     68: A-1-  B01--  C01--  D---3
     69: A-1-  B01--  C--23  D01--
     70: A-1-  B01--  C--23  D--2-
     71: A-1-  B01--  C--23  D---3
     72: A--2  B01--  C0-2-  D-1--
     73: A--2  B01--  C0-2-  D---3
     74: A--2  B01--  C-1-3  D0-2-
     75: A--2  B01--  C-1-3  D-1--
     76: A--2  B01--  C-1-3  D---3

The above allow some programs to be compiled but with restrictions that make most useful programs impossible: Numbers 67 and 72 warn about any user-defined symbol names (such as SUBROUTINE FOO); Numbers 68 and 73 warn about any user-defined symbol names longer than one character that don't have at least one non-alphabetic character after the first; Numbers 69 and 74 disallow any references to intrinsics; and Numbers 70, 71, 75, and 76 are combinations of the restrictions in 67+69, 68+69, 72+74, and 73+74, respectively.

All redundant combinations are shown in the above tables anyplace where more than one setting is shown for a low-level switch. For example, B0-2- means either setting 0 or 2 is valid for switch B. The ``proper'' setting in such a case is the one that copies the setting of switch A---any other setting might slightly reduce the speed of the compiler, though possibly to an unmeasurable extent.

All remaining combinations are useless in that they prevent successful compilation of non-null source files (source files with something other than comments).

VXT Fortran
===========

g77 supports certain constructs that have different meanings in VXT Fortran than they do in the GNU Fortran language.

Generally, this manual uses the invented term VXT Fortran to refer VAX FORTRAN (circa v4). That compiler offered many popular features, though not necessarily those that are specific to the VAX processor architecture, the VMS operating system, or Digital Equipment Corporation's Fortran product line. (VAX and VMS probably are trademarks of Digital Equipment Corporation.)

An extension offered by a Digital Fortran product that also is offered by several other Fortran products for different kinds of systems is probably going to be considered for inclusion in g77 someday, and is considered a VXT Fortran feature.

The -fvxt option generally specifies that, where the meaning of a construct is ambiguous (means one thing in GNU Fortran and another in VXT Fortran), the VXT Fortran meaning is to be assumed.

Meaning of Double Quote
-----------------------

g77 treats double-quote (") as beginning an octal constant of INTEGER(KIND=1) type when the -fvxt option is specified. The form of this octal constant is

     "OCTAL-DIGITS

where OCTAL-DIGITS is a nonempty string of characters in the set 01234567.

For example, the -fvxt option permits this:

     PRINT *, "20
     END

The above program would print the value 16.

See Integer Type, for information on the preferred construct for integer constants specified using GNU Fortran's octal notation.

(In the GNU Fortran language, the double-quote character (") delimits a character constant just as does apostrophe ('). There is no way to allow both constructs in the general case, since statements like PRINT *,"2000 !comment?" would be ambiguous.)

Meaning of Exclamation Point in Column 6
----------------------------------------

g77 treats an exclamation point (!) in column 6 of a fixed-form source file as a continuation character rather than as the beginning of a comment (as it does in any other column) when the -fvxt option is specified.

The following program, when run, prints a message indicating whether it is interpreted according to GNU Fortran (and Fortran 90) rules or VXT Fortran rules:

     C234567  (This line begins in column 1.)
           I = 0
          !1
           IF (I.EQ.0) PRINT *, ' I am a VXT Fortran program'
           IF (I.EQ.1) PRINT *, ' I am a Fortran 90 program'
           IF (I.LT.0 .OR. I.GT.1) PRINT *, ' I am a HAL 9000 computer'
           END

(In the GNU Fortran and Fortran 90 languages, exclamation point is a valid character and, unlike space (SPC) or zero (0), marks a line as a continuation line when it appears in column 6.)

Fortran 90
==========

The GNU Fortran language includes a number of features that are part of Fortran 90, even when the -ff90 option is not specified. The features enabled by -ff90 are intended to be those that, when -ff90 is not specified, would have another meaning to g77---usually meaning something invalid in the GNU Fortran language.

So, the purpose of -ff90 is not to specify whether g77 is to gratuitously reject Fortran 90 constructs. The -pedantic option specified with -fno-f90 is intended to do that, although its implementation is certainly incomplete at this point.

When -ff90 is specified:

  * The type of REAL(EXPR) and AIMAG(EXPR), where EXPR is COMPLEX type, is the same type as the real part of EXPR.

     For example, assuming Z is type COMPLEX(KIND=2), REAL(Z) would return a value of type REAL(KIND=2), not of type REAL(KIND=1), since -ff90 is specified.

Pedantic Compilation
====================

The -fpedantic command-line option specifies that g77 is to warn about code that is not standard-conforming. This is useful for finding some extensions g77 accepts that other compilers might not accept. (Note that the -pedantic and -pedantic-errors options always imply -fpedantic.)

With -fno-f90 in force, ANSI FORTRAN 77 is used as the standard for conforming code. With -ff90 in force, Fortran 90 is used.

The constructs for which g77 issues diagnostics when -fpedantic and -fno-f90 are in force are:

  * Automatic arrays, as in

          SUBROUTINE X(N)
          REAL A(N)
          ...

     where A is not listed in any ENTRY statement, and thus is not a dummy argument.

  * The commas in READ (5), I and WRITE (10), J.

     These commas are disallowed by FORTRAN 77, but, while strictly superfluous, are syntactically elegant, especially given that commas are required in statements such as READ 99, I and PRINT *, J. Many compilers permit the superfluous commas for this reason.

  * DOUBLE COMPLEX, either explicitly or implicitly.

     An explicit use of this type is via a DOUBLE COMPLEX or IMPLICIT DOUBLE COMPLEX statement, for examples.

     An example of an implicit use is the expression C*D, where C is COMPLEX(KIND=1) and D is DOUBLE PRECISION. This expression is prohibited by ANSI FORTRAN 77 because the rules of promotion would suggest that it produce a DOUBLE COMPLEX result---a type not provided for by that standard.

  * Automatic conversion of numeric expressions to INTEGER(KIND=1) in contexts such as:

       - Array-reference indexes.

       - Alternate-return values.

       - Computed GOTO.

       - FORMAT run-time expressions (not yet supported).

       - Dimension lists in specification statements.

       - Numbers for I/O statements (such as READ (UNIT=3.2), I)

       - Sizes of CHARACTER entities in specification statements.

       - Kind types in specification entities (a Fortran 90 feature).

       - Initial, terminal, and incrementation parameters for implied-DO constructs in DATA statements.

  * Automatic conversion of LOGICAL expressions to INTEGER in contexts such as arithmetic IF (where COMPLEX expressions are disallowed anyway).

  * Zero-size array dimensions, as in:

          INTEGER I(10,20,4:2)

  * Zero-length CHARACTER entities, as in:

          PRINT *, ''

  * Substring operators applied to character constants and named constants, as in:

          PRINT *, 'hello'(3:5)

  * Null arguments passed to statement function, as in:

          PRINT *, FOO(,3)

  * Disagreement among program units regarding whether a given COMMON area is SAVEd (for targets where program units in a single source file are ``glued'' together as they typically are for UNIX development environments).

  * Disagreement among program units regarding the size of a named COMMON block.

  * Specification statements following first DATA statement.

     (In the GNU Fortran language, DATA I/1/ may be followed by INTEGER J, but not INTEGER I. The -fpedantic option disallows both of these.)

  * Semicolon as statement separator, as in:

          CALL FOO; CALL BAR

  * Use of & in column 1 of fixed-form source (to indicate continuation).

  * Use of CHARACTER constants to initialize numeric entities, and vice versa.

  * Expressions having two arithmetic operators in a row, such as X*-Y.

If -fpedantic is specified along with -ff90, the following constructs result in diagnostics:

  * Use of semicolon as a statement separator on a line that has an INCLUDE directive.

Distensions
===========

The -fugly-* command-line options determine whether certain features supported by VAX FORTRAN and other such compilers, but considered too ugly to be in code that can be changed to use safer and/or more portable constructs, are accepted. These are humorously referred to as ``distensions'', extensions that just plain look ugly in the harsh light of day.

Implicit Argument Conversion
----------------------------

The -fno-ugly-args option disables passing typeless and Hollerith constants as actual arguments in procedure invocations. For example:

     CALL FOO(4HABCD)
     CALL BAR('123'O)

These constructs can be too easily used to create non-portable code, but are not considered as ``ugly'' as others. Further, they are widely used in existing Fortran source code in ways that often are quite portable. Therefore, they are enabled by default.

Ugly Assumed-Size Arrays
------------------------

The -fugly-assumed option enables the treatment of any array with a final dimension specified as 1 as an assumed-size array, as if * had been specified instead.

For example, DIMENSION X(1) is treated as if it had read DIMENSION X(*) if X is listed as a dummy argument in a preceding SUBROUTINE, FUNCTION, or ENTRY statement in the same program unit.

Use an explicit lower bound to avoid this interpretation. For example, DIMENSION X(1:1) is never treated as if it had read DIMENSION X(*) or DIMENSION X(1:*). Nor is DIMENSION X(2-1) affected by this option, since that kind of expression is unlikely to have been intended to designate an assumed-size array.

This option is used to prevent warnings being issued about apparent out-of-bounds reference such as X(2) = 99.

It also prevents the array from being used in contexts that disallow assumed-size arrays, such as PRINT *,X. In such cases, a diagnostic is generated and the source file is not compiled.

The construct affected by this option is used only in old code that pre-exists the widespread acceptance of adjustable and assumed-size arrays in the Fortran community.

Note: This option does not affect how DIMENSION X(1) is treated if X is listed as a dummy argument only after the DIMENSION statement (presumably in an ENTRY statement). For example, -fugly-assumed has no effect on the following program unit:

     SUBROUTINE X
     REAL A(1)
     RETURN
     ENTRY Y(A)
     PRINT *, A
     END

Ugly Complex Part Extraction
----------------------------

The -fugly-complex option enables use of the REAL() and AIMAG() intrinsics with arguments that are COMPLEX types other than COMPLEX(KIND=1).

With -ff90 in effect, these intrinsics return the unconverted real and imaginary parts (respectively) of their argument.

With -fno-f90 in effect, these intrinsics convert the real and imaginary parts to REAL(KIND=1), and return the result of that conversion.

Due to this ambiguity, the GNU Fortran language defines these constructs as invalid, except in the specific case where they are entirely and solely passed as an argument to an invocation of the REAL() intrinsic. For example,

     REAL(REAL(Z))

is permitted even when Z is COMPLEX(KIND=2) and -fno-ugly-complex is in effect, because the meaning is clear.

g77 enforces this restriction, unless -fugly-complex is specified, in which case the appropriate interpretation is chosen and no diagnostic is issued.

See CMPAMBIG, for information on how to cope with existing code with unclear expectations of REAL() and AIMAG() with COMPLEX(KIND=2) arguments.

See RealPart Intrinsic, for information on the REALPART() intrinsic, used to extract the real part of a complex expression without conversion. See ImagPart Intrinsic, for information on the IMAGPART() intrinsic, used to extract the imaginary part of a complex expression without conversion.

Ugly Null Arguments
-------------------

The -fugly-comma option enables use of a single trailing comma to mean ``pass an extra trailing null argument'' in a list of actual arguments to an external procedure, and use of an empty list of arguments to such a procedure to mean ``pass a single null argument''.

(Null arguments often are used in some procedure-calling schemes to indicate omitted arguments.)

For example, CALL FOO(,) means ``pass two null arguments'', rather than ``pass one null argument''. Also, CALL BAR() means ``pass one null argument''.

This construct is considered ``ugly'' because it does not provide an elegant way to pass a single null argument that is syntactically distinct from passing no arguments. That is, this construct changes the meaning of code that makes no use of the construct.

So, with -fugly-comma in force, CALL FOO() and I = JFUNC() pass a single null argument, instead of passing no arguments as required by the Fortran 77 and 90 standards.

Note: Many systems gracefully allow the case where a procedure call passes one extra argument that the called procedure does not expect.

So, in practice, there might be no difference in the behavior of a program that does CALL FOO() or I = JFUNC() and is compiled with -fugly-comma in force as compared to its behavior when compiled with the default, -fno-ugly-comma, in force, assuming FOO and JFUNC do not expect any arguments to be passed.

Ugly Conversion of Initializers
-------------------------------

The constructs disabled by -fno-ugly-init are:

  * Use of Hollerith and typeless constants in contexts where they set initial (compile-time) values for variables, arrays, and named constants---that is, DATA and PARAMETER statements, plus type-declaration statements specifying initial values.

     Here are some sample initializations that are disabled by the -fno-ugly-init option:

          PARAMETER (VAL='9A304FFE'X)
          REAL*8 STRING/8HOUTPUT00/
          DATA VAR/4HABCD/

  * In the same contexts as above, use of character constants to initialize numeric items and vice versa (one constant per item).

     Here are more sample initializations that are disabled by the -fno-ugly-init option:

          INTEGER IA
          CHARACTER BELL
          PARAMETER (IA = 'A')
          PARAMETER (BELL = 7)

  * Use of Hollerith and typeless constants on the right-hand side of assignment statements to numeric types, and in other contexts (such as passing arguments in invocations of intrinsic procedures and statement functions) that are treated as assignments to known types (the dummy arguments, in these cases).

     Here are sample statements that are disabled by the -fno-ugly-init option:

          IVAR = 4HABCD
          PRINT *, IMAX0(2HAB, 2HBA)

The above constructs, when used, can tend to result in non-portable code. But, they are widely used in existing Fortran code in ways that often are quite portable. Therefore, they are enabled by default.

Ugly Integer Conversions
------------------------

The constructs enabled via -fugly-logint are:

  * Automatic conversion between INTEGER and LOGICAL as dictated by context (typically implies nonportable dependencies on how a particular implementation encodes .TRUE. and .FALSE.).

  * Use of a LOGICAL variable in ASSIGN and assigned-GOTO statements.

The above constructs are disabled by default because use of them tends to lead to non-portable code. Even existing Fortran code that uses that often turns out to be non-portable, if not outright buggy.

Some of this is due to differences among implementations as far as how .TRUE. and .FALSE. are encoded as INTEGER values---Fortran code that assumes a particular coding is likely to use one of the above constructs, and is also likely to not work correctly on implementations using different encodings.

See Equivalence Versus Equality, for more information.

Ugly Assigned Labels
--------------------

The -fugly-assign option forces g77 to use the same storage for assigned labels as it would for a normal assignment to the same variable.

For example, consider the following code fragment:

     I = 3
     ASSIGN 10 TO I

Normally, for portability and improved diagnostics, g77 reserves distinct storage for a ``sibling'' of I, used only for ASSIGN statements to that variable (along with the corresponding assigned-GOTO and assigned-FORMAT-I/O statements that reference the variable).

However, some code (that violates the ANSI FORTRAN 77 standard) attempts to copy assigned labels among variables involved with ASSIGN statements, as in:

     ASSIGN 10 TO I
     ISTATE(5) = I
     ...
     J = ISTATE(ICUR)
     GOTO J

Such code doesn't work under g77 unless -fugly-assign is specified on the command-line, ensuring that the value of I referenced in the second line is whatever value g77 uses to designate statement label 10, so the value may be copied into the ISTATE array, later retrieved into a variable of the appropriate type (J), and used as the target of an assigned-GOTO statement.

Note: To avoid subtle program bugs, when -fugly-assign is specified, g77 requires the type of variables specified in assigned-label contexts must be the same type returned by %LOC(). On many systems, this type is effectively the same as INTEGER(KIND=1), while, on others, it is effectively the same as INTEGER(KIND=2).

Do not depend on g77 actually writing valid pointers to these variables, however. While g77 currently chooses that implementation, it might be changed in the future.

See Assigned Statement Labels (ASSIGN and GOTO), for implementation details on assigned-statement labels.

The GNU Fortran Compiler
************************

The GNU Fortran compiler, g77, supports programs written in the GNU Fortran language and in some other dialects of Fortran.

Some aspects of how g77 works are universal regardless of dialect, and yet are not properly part of the GNU Fortran language itself. These are described below.

Note: This portion of the documentation definitely needs a lot of work!

Compiler Limits
===============

g77, as with GNU tools in general, imposes few arbitrary restrictions on lengths of identifiers, number of continuation lines, number of external symbols in a program, and so on.

For example, some other Fortran compiler have an option (such as -NlX) to increase the limit on the number of continuation lines. Also, some Fortran compilation systems have an option (such as -NxX) to increase the limit on the number of external symbols.

g77, gcc, and GNU ld (the GNU linker) have no equivalent options, since they do not impose arbitrary limits in these areas.

g77 does currently limit the number of dimensions in an array to the same degree as do the Fortran standards---seven (7). This restriction might be lifted in a future version.

Run-time Environment Limits
===========================

As a portable Fortran implementation, g77 offers its users direct access to, and otherwise depends upon, the underlying facilities of the system used to build g77, the system on which g77 itself is used to compile programs, and the system on which the g77-compiled program is actually run. (For most users, the three systems are of the same type---combination of operating environment and hardware---often the same physical system.)

The run-time environment for a particular system inevitably imposes some limits on a program's use of various system facilities. These limits vary from system to system.

Even when such limits might be well beyond the possibility of being encountered on a particular system, the g77 run-time environment has certain built-in limits, usually, but not always, stemming from intrinsics with inherently limited interfaces.

Currently, the g77 run-time environment does not generally offer a less-limiting environment by augmenting the underlying system's own environment.

Therefore, code written in the GNU Fortran language, while syntactically and semantically portable, might nevertheless make non-portable assumptions about the run-time environment---assumptions that prove to be false for some particular environments.

The GNU Fortran language, the g77 compiler and run-time environment, and the g77 documentation do not yet offer comprehensive portable work-arounds for such limits, though programmers should be able to find their own in specific instances.

Not all of the limitations are described in this document. Some of the known limitations include:

Timer Wraparounds
-----------------

Intrinsics that return values computed from system timers, whether elapsed (wall-clock) timers, process CPU timers, or other kinds of timers, are prone to experiencing wrap-around errors (or returning wrapped-around values from successive calls) due to insufficient ranges offered by the underlying system's timers.

Some of the symptoms of such behaviors include apparently negative time being computed for a duration, an extremely short amount of time being computed for a long duration, and an extremely long amount of time being computed for a short duration.

See the following for intrinsics known to have potential problems in these areas on at least some systems: CPU_Time Intrinsic, DTime Intrinsic (function), DTime Intrinsic (subroutine), ETime Intrinsic (function), ETime Intrinsic (subroutine), MClock Intrinsic, MClock8 Intrinsic, Secnds Intrinsic, Second Intrinsic (function), Second Intrinsic (subroutine), System_Clock Intrinsic, Time Intrinsic (UNIX), Time Intrinsic (VXT), Time8 Intrinsic.

Year 2000 (Y2K) Problems
------------------------

While the g77 compiler itself is believed to be Year-2000 (Y2K) compliant, some intrinsics are not, and, potentially, some underlying systems are not, perhaps rendering some Y2K-compliant intrinsics non-compliant when used on those particular systems.

Fortran code that uses non-Y2K-compliant intrinsics (listed below) is, itself, almost certainly not compliant, and should be modified to use Y2K-compliant intrinsics instead.

Fortran code that uses no non-Y2K-compliant intrinsics, but which currently is running on a non-Y2K-compliant system, can be made more Y2K compliant by compiling and linking it for use on a new Y2K-compliant system, such as a new version of an old, non-Y2K-compliant, system.

Currently, information on Y2K and related issues is being maintained at http://www.gnu.org/software/year2000-list.html.

See the following for intrinsics known to have potential problems in these areas on at least some systems: Date Intrinsic, IDate Intrinsic (VXT).

The libg2c library shipped with any g77 that warns about invocation of a non-Y2K-compliant intrinsic has renamed the EXTERNAL procedure names of those intrinsics. This is done so that the libg2c implementations of these intrinsics cannot be directly linked to as EXTERNAL names (which normally would avoid the non-Y2K-intrinsic warning).

The renamed forms of the EXTERNAL names of these renamed procedures may be linked to by appending the string _y2kbug to the name of the procedure in the source code. For example:

     CHARACTER*20 STR
     INTEGER YY, MM, DD
     EXTERNAL DATE_Y2KBUG, VXTIDATE_Y2KBUG
     CALL DATE_Y2KBUG (STR)
     CALL VXTIDATE_Y2KBUG (MM, DD, YY)

(Note that the EXTERNAL statement is not actually required, since the modified names are not recognized as intrinsics by the current version of g77. But it is shown in this specific case, for purposes of illustration.)

The renaming of EXTERNAL procedure names of these intrinsics causes unresolved references at link time. For example, EXTERNAL DATE; CALL DATE(STR) is normally compiled by g77 as, in C, date_(&str, 20);. This, in turn, links to the date_ procedure in the libE77 portion of libg2c, which purposely calls a nonexistent procedure named G77_date_y2kbuggy_0. The resulting link-time error is designed, via this name, to encourage the programmer to look up the index entries to this portion of the g77 documentation.

Generally, we recommend that the EXTERNAL method of invoking procedures in libg2c not be used. When used, some of the correctness checking normally performed by g77 is skipped.

In particular, it is probably better to use the INTRINSIC method of invoking non-Y2K-compliant procedures, so anyone compiling the code can quickly notice the potential Y2K problems (via the warnings printing by g77) without having to even look at the code itself.

If there are problems linking libg2c to code compiled by g77 that involve the string y2kbug, and these are not explained above, that probably indicates that a version of libg2c older than g77 is being linked to, or that the new library is being linked to code compiled by an older version of g77.

That's because, as of the version that warns about non-Y2K-compliant intrinsic invocation, g77 references the libg2c implementations of those intrinsics using new names, containing the string y2kbug.

So, linking newly-compiled code (invoking one of the intrinsics in question) to an old library might yield an unresolved reference to G77_date_y2kbug_0. (The old library calls it G77_date_0.)

Similarly, linking previously-compiled code to a new library might yield an unresolved reference to G77_vxtidate_0. (The new library calls it G77_vxtidate_y2kbug_0.)

The proper fix for the above problems is to obtain the latest release of g77 and related products (including libg2c) and install them on all systems, then recompile, relink, and install (as appropriate) all existing Fortran programs.

(Normally, this sort of renaming is steadfastly avoided. In this case, however, it seems more important to highlight potential Y2K problems than to ease the transition of potentially non-Y2K-compliant code to new versions of g77 and libg2c.)

Array Size
----------

Currently, g77 uses the default INTEGER type for array indexes, which limits the sizes of single-dimension arrays on systems offering a larger address space than can be addressed by that type. (That g77 puts all arrays in memory could be considered another limitation---it could use large temporary files---but that decision is left to the programmer as an implementation choice by most Fortran implementations.)

It is not yet clear whether this limitation never, sometimes, or always applies to the sizes of multiple-dimension arrays as a whole.

For example, on a system with 64-bit addresses and 32-bit default INTEGER, an array with a size greater than can be addressed by a 32-bit offset can be declared using multiple dimensions. Such an array is therefore larger than a single-dimension array can be, on the same system.

Whether large multiple-dimension arrays are reliably supported depends mostly on the gcc back end (code generator) used by g77, and has not yet been fully investigated.

Character-variable Length
-------------------------

Currently, g77 uses the default INTEGER type for the lengths of CHARACTER variables and array elements.

This means that, for example, a system with a 64-bit address space and a 32-bit default INTEGER type does not, under g77, support a CHARACTER*N declaration where N is greater than 2147483647.

Year 10000 (Y10K) Problems
--------------------------

Most intrinsics returning, or computing values based on, date information are prone to Year-10000 (Y10K) problems, due to supporting only 4 digits for the year.

See the following for examples: FDate Intrinsic (function), FDate Intrinsic (subroutine), IDate Intrinsic (UNIX), Time Intrinsic (VXT), Date_and_Time Intrinsic.

Compiler Types
==============

Fortran implementations have a fair amount of freedom given them by the standard as far as how much storage space is used and how much precision and range is offered by the various types such as LOGICAL(KIND=1), INTEGER(KIND=1), REAL(KIND=1), REAL(KIND=2), COMPLEX(KIND=1), and CHARACTER. Further, many compilers offer so-called *N notation, but the interpretation of N varies across compilers and target architectures.

The standard requires that LOGICAL(KIND=1), INTEGER(KIND=1), and REAL(KIND=1) occupy the same amount of storage space, and that COMPLEX(KIND=1) and REAL(KIND=2) take twice as much storage space as REAL(KIND=1). Further, it requires that COMPLEX(KIND=1) entities be ordered such that when a COMPLEX(KIND=1) variable is storage-associated (such as via EQUIVALENCE) with a two-element REAL(KIND=1) array named R, R(1) corresponds to the real element and R(2) to the imaginary element of the COMPLEX(KIND=1) variable.

(Few requirements as to precision or ranges of any of these are placed on the implementation, nor is the relationship of storage sizes of these types to the CHARACTER type specified, by the standard.)

g77 follows the above requirements, warning when compiling a program requires placement of items in memory that contradict the requirements of the target architecture. (For example, a program can require placement of a REAL(KIND=2) on a boundary that is not an even multiple of its size, but still an even multiple of the size of a REAL(KIND=1) variable. On some target architectures, using the canonical mapping of Fortran types to underlying architectural types, such placement is prohibited by the machine definition or the Application Binary Interface (ABI) in force for the configuration defined for building gcc and g77. g77 warns about such situations when it encounters them.)

g77 follows consistent rules for configuring the mapping between Fortran types, including the *N notation, and the underlying architectural types as accessed by a similarly-configured applicable version of the gcc compiler. These rules offer a widely portable, consistent Fortran/C environment, although they might well conflict with the expectations of users of Fortran compilers designed and written for particular architectures.

These rules are based on the configuration that is in force for the version of gcc built in the same release as g77 (and which was therefore used to build both the g77 compiler components and the libg2c run-time library):

REAL(KIND=1)
     Same as float type.

REAL(KIND=2)
     Same as whatever floating-point type that is twice the size of a float---usually, this is a double.

INTEGER(KIND=1)
     Same as an integral type that is occupies the same amount of memory storage as float---usually, this is either an int or a long int.

LOGICAL(KIND=1)
     Same gcc type as INTEGER(KIND=1).

INTEGER(KIND=2)
     Twice the size, and usually nearly twice the range, as INTEGER(KIND=1)---usually, this is either a long int or a long long int.

LOGICAL(KIND=2)
     Same gcc type as INTEGER(KIND=2).

INTEGER(KIND=3)
     Same gcc type as signed char.

LOGICAL(KIND=3)
     Same gcc type as INTEGER(KIND=3).

INTEGER(KIND=6)
     Twice the size, and usually nearly twice the range, as INTEGER(KIND=3)---usually, this is a short.

LOGICAL(KIND=6)
     Same gcc type as INTEGER(KIND=6).

COMPLEX(KIND=1)
     Two REAL(KIND=1) scalars (one for the real part followed by one for the imaginary part).

COMPLEX(KIND=2)
     Two REAL(KIND=2) scalars.

NUMERIC-TYPE*N
     (Where NUMERIC-TYPE is any type other than CHARACTER.) Same as whatever gcc type occupies N times the storage space of a gcc char item.

DOUBLE PRECISION
     Same as REAL(KIND=2).

DOUBLE COMPLEX
     Same as COMPLEX(KIND=2).

Note that the above are proposed correspondences and might change in future versions of g77---avoid writing code depending on them.

Other types supported by g77 are derived from gcc types such as char, short, int, long int, long long int, long double, and so on. That is, whatever types gcc already supports, g77 supports now or probably will support in a future version. The rules for the NUMERIC-TYPE*N notation apply to these types, and new values for NUMERIC-TYPE(KIND=N) will be assigned in a way that encourages clarity, consistency, and portability.

Compiler Constants
==================

g77 strictly assigns types to all constants not documented as ``typeless'' (typeless constants including '1'Z, for example). Many other Fortran compilers attempt to assign types to typed constants based on their context. This results in hard-to-find bugs, nonportable code, and is not in the spirit (though it strictly follows the letter) of the 77 and 90 standards.

g77 might offer, in a future release, explicit constructs by which a wider variety of typeless constants may be specified, and/or user-requested warnings indicating places where g77 might differ from how other compilers assign types to constants.

See Context-Sensitive Constants, for more information on this issue.

Compiler Intrinsics
===================

g77 offers an ever-widening set of intrinsics. Currently these all are procedures (functions and subroutines).

Some of these intrinsics are unimplemented, but their names reserved to reduce future problems with existing code as they are implemented. Others are implemented as part of the GNU Fortran language, while yet others are provided for compatibility with other dialects of Fortran but are not part of the GNU Fortran language.

To manage these distinctions, g77 provides intrinsic groups, a facility that is simply an extension of the intrinsic groups provided by the GNU Fortran language.

Intrinsic Groups
----------------

A given specific intrinsic belongs in one or more groups. Each group is deleted, disabled, hidden, or enabled by default or a command-line option. The meaning of each term follows.

Deleted
     No intrinsics are recognized as belonging to that group.

Disabled
     Intrinsics are recognized as belonging to the group, but references to them (other than via the INTRINSIC statement) are disallowed through that group.

Hidden
     Intrinsics in that group are recognized and enabled (if implemented) only if the first mention of the actual name of an intrinsic in a program unit is in an INTRINSIC statement.

Enabled
     Intrinsics in that group are recognized and enabled (if implemented).

The distinction between deleting and disabling a group is illustrated by the following example. Assume intrinsic FOO belongs only to group FGR. If group FGR is deleted, the following program unit will successfully compile, because FOO() will be seen as a reference to an external function named FOO:

     PRINT *, FOO()
     END

If group FGR is disabled, compiling the above program will produce diagnostics, either because the FOO intrinsic is improperly invoked or, if properly invoked, it is not enabled. To change the above program so it references an external function FOO instead of the disabled FOO intrinsic, add the following line to the top:

     EXTERNAL FOO

So, deleting a group tells g77 to pretend as though the intrinsics in that group do not exist at all, whereas disabling it tells g77 to recognize them as (disabled) intrinsics in intrinsic-like contexts.

Hiding a group is like enabling it, but the intrinsic must be first named in an INTRINSIC statement to be considered a reference to the intrinsic rather than to an external procedure. This might be the ``safest'' way to treat a new group of intrinsics when compiling old code, because it allows the old code to be generally written as if those new intrinsics never existed, but to be changed to use them by inserting INTRINSIC statements in the appropriate places. However, it should be the goal of development to use EXTERNAL for all names of external procedures that might be intrinsic names.

If an intrinsic is in more than one group, it is enabled if any of its containing groups are enabled; if not so enabled, it is hidden if any of its containing groups are hidden; if not so hidden, it is disabled if any of its containing groups are disabled; if not so disabled, it is deleted. This extra complication is necessary because some intrinsics, such as IBITS, belong to more than one group, and hence should be enabled if any of the groups to which they belong are enabled, and so on.

The groups are:

badu77
     UNIX intrinsics having inappropriate forms (usually functions that have intended side effects).

gnu
     Intrinsics the GNU Fortran language supports that are extensions to the Fortran standards (77 and 90).

f2c
     Intrinsics supported by AT&T's f2c converter and/or libf2c.

f90
     Fortran 90 intrinsics.

mil
     MIL-STD 1753 intrinsics (MVBITS, IAND, BTEST, and so on).

unix
     UNIX intrinsics (IARGC, EXIT, ERF, and so on).

vxt
     VAX/VMS FORTRAN (current as of v4) intrinsics.

Other Intrinsics
----------------

g77 supports intrinsics other than those in the GNU Fortran language proper. This set of intrinsics is described below.

(Note that the empty lines appearing in the menu below are not intentional---they result from a bug in the makeinfo program.)

     [file intdoc.texi not included]

Other Compilers
***************

An individual Fortran source file can be compiled to an object (*.o) file instead of to the final program executable. This allows several portions of a program to be compiled at different times and linked together whenever a new version of the program is needed. However, it introduces the issue of object compatibility across the various object files (and libraries, or *.a files) that are linked together to produce any particular executable file.

Object compatibility is an issue when combining, in one program, Fortran code compiled by more than one compiler (or more than one configuration of a compiler). If the compilers disagree on how to transform the names of procedures, there will normally be errors when linking such programs. Worse, if the compilers agree on naming, but disagree on issues like how to pass parameters, return arguments, and lay out COMMON areas, the earliest detected errors might be the incorrect results produced by the program (and that assumes these errors are detected, which is not always the case).

Normally, g77 generates code that is object-compatible with code generated by a version of f2c configured (with, for example, f2c.h definitions) to be generally compatible with g77 as built by gcc. (Normally, f2c will, by default, conform to the appropriate configuration, but it is possible that older or perhaps even newer versions of f2c, or versions having certain configuration changes to f2c internals, will produce object files that are incompatible with g77.)

For example, a Fortran string subroutine argument will become two arguments on the C side: a char * and an int length.

Much of this compatibility results from the fact that g77 uses the same run-time library, libf2c, used by f2c, though g77 gives its version the name libg2c so as to avoid conflicts when linking, installing them in the same directories, and so on.

Other compilers might or might not generate code that is object-compatible with libg2c and current g77, and some might offer such compatibility only when explicitly selected via a command-line option to the compiler.

Note: This portion of the documentation definitely needs a lot of work!

Dropping f2c Compatibility
==========================

Specifying -fno-f2c allows g77 to generate, in some cases, faster code, by not needing to allow to the possibility of linking with code compiled by f2c.

For example, this affects how REAL(KIND=1), COMPLEX(KIND=1), and COMPLEX(KIND=2) functions are called. With -fno-f2c, they are compiled as returning the appropriate gcc type (float, __complex__ float, __complex__ double, in many configurations).

With -ff2c in force, they are compiled differently (with perhaps slower run-time performance) to accommodate the restrictions inherent in f2c's use of K&R C as an intermediate language---REAL(KIND=1) functions return C's double type, while COMPLEX functions return void and use an extra argument pointing to a place for the functions to return their values.

It is possible that, in some cases, leaving -ff2c in force might produce faster code than using -fno-f2c. Feel free to experiment, but remember to experiment with changing the way entire programs and their Fortran libraries are compiled at a time, since this sort of experimentation affects the interface of code generated for a Fortran source file---that is, it affects object compatibility.

Note that f2c compatibility is a fairly static target to achieve, though not necessarily perfectly so, since, like g77, it is still being improved. However, specifying -fno-f2c causes g77 to generate code that will probably be incompatible with code generated by future versions of g77 when the same option is in force. You should make sure you are always able to recompile complete programs from source code when upgrading to new versions of g77 or f2c, especially when using options such as -fno-f2c.

Therefore, if you are using g77 to compile libraries and other object files for possible future use and you don't want to require recompilation for future use with subsequent versions of g77, you might want to stick with f2c compatibility for now, and carefully watch for any announcements about changes to the f2c/libf2c interface that might affect existing programs (thus requiring recompilation).

It is probable that a future version of g77 will not, by default, generate object files compatible with f2c, and that version probably would no longer use libf2c. If you expect to depend on this compatibility in the long term, use the options -ff2c -ff2c-library when compiling all of the applicable code. This should cause future versions of g77 either to produce compatible code (at the expense of the availability of some features and performance), or at the very least, to produce diagnostics.

(The library g77 produces will no longer be named libg2c when it is no longer generally compatible with libf2c. It will likely be referred to, and, if installed as a distinct library, named libg77, or some other as-yet-unused name.)

Compilers Other Than f2c
========================

On systems with Fortran compilers other than f2c and g77, code compiled by g77 is not expected to work well with code compiled by the native compiler. (This is true for f2c-compiled objects as well.) Libraries compiled with the native compiler probably will have to be recompiled with g77 to be used with g77-compiled code.

Reasons for such incompatibilities include:

  * There might be differences in the way names of Fortran procedures are translated for use in the system's object-file format. For example, the statement CALL FOO might be compiled by g77 to call a procedure the linker ld sees given the name _foo_, while the apparently corresponding statement SUBROUTINE FOO might be compiled by the native compiler to define the linker-visible name _foo, or _FOO_, and so on.

  * There might be subtle type mismatches which cause subroutine arguments and function return values to get corrupted.

     This is why simply getting g77 to transform procedure names the same way a native compiler does is not usually a good idea---unless some effort has been made to ensure that, aside from the way the two compilers transform procedure names, everything else about the way they generate code for procedure interfaces is identical.

  * Native compilers use libraries of private I/O routines which will not be available at link time unless you have the native compiler---and you would have to explicitly ask for them.

     For example, on the Sun you would have to add -L/usr/lang/SCx.x -lF77 -lV77 to the link command.

Other Languages
***************

Note: This portion of the documentation definitely needs a lot of work!

Tools and advice for interoperating with C and C++
==================================================

The following discussion assumes that you are running g77 in f2c compatibility mode, i.e. not using -fno-f2c. It provides some advice about quick and simple techniques for linking Fortran and C (or C++), the most common requirement. For the full story consult the description of code generation. See Debugging and Interfacing.

When linking Fortran and C, it's usually best to use g77 to do the linking so that the correct libraries are included (including the maths one). If you're linking with C++ you will want to add -lstdc++, -lg++ or whatever. If you need to use another driver program (or ld directly), you can find out what linkage options g77 passes by running g77 -v.

C Interfacing Tools
-------------------

Even if you don't actually use it as a compiler, f2c from ftp://ftp.netlib.org/f2c/src, can be a useful tool when you're interfacing (linking) Fortran and C. See Generating Skeletons and Prototypes with f2c.

To use f2c for this purpose you only need retrieve and build the src directory from the distribution, consult the README instructions there for machine-specifics, and install the f2c program on your path.

Something else that might be useful is cfortran.h from ftp://zebra.desy.de/cfortran. This is a fairly general tool which can be used to generate interfaces for calling in both directions between Fortran and C. It can be used in f2c mode with g77---consult its documentation for details.

Accessing Type Information in C
-------------------------------

Generally, C code written to link with g77 code---calling and/or being called from Fortran---should #include <g2c.h> to define the C versions of the Fortran types. Don't assume Fortran INTEGER types correspond to C ints, for instance; instead, declare them as integer, a type defined by g2c.h. g2c.h is installed where gcc will find it by default, assuming you use a copy of gcc compatible with g77, probably built at the same time as g77.

Generating Skeletons and Prototypes with f2c
--------------------------------------------

A simple and foolproof way to write g77-callable C routines---e.g. to interface with an existing library---is to write a file (named, for example, fred.f) of dummy Fortran skeletons comprising just the declaration of the routine(s) and dummy arguments plus END statements. Then run f2c on file fred.f to produce fred.c into which you can edit useful code, confident the calling sequence is correct, at least. (There are some errors otherwise commonly made in generating C interfaces with f2c conventions, such as not using doublereal as the return type of a REAL FUNCTION.)

f2c also can help with calling Fortran from C, using its -P option to generate C prototypes appropriate for calling the Fortran. (The files generated like this can also be used for inter-unit consistency checking of dummy and actual arguments, although the ftnchek tool from ftp://ftp.netlib.org/fortran or ftp://ftp.dsm.fordham.edu is probably better for this purpose.) If the Fortran code containing any routines to be called from C is in file joe.f, use the command f2c -P joe.f to generate the file joe.P containing prototype information. #include this in the C which has to call the Fortran routines to make sure you get it right.

See Arrays (DIMENSION), for information on the differences between the way Fortran (including compilers like g77) and C handle arrays.

C++ Considerations
------------------

f2c can be used to generate suitable code for compilation with a C++ system using the -C++ option. The important thing about linking g77-compiled code with C++ is that the prototypes for the g77 routines must specify C linkage to avoid name mangling. So, use an extern "C" declaration. f2c's -C++ option will not take care of this when generating skeletons or prototype files as above, however, it will avoid clashes with C++ reserved words in addition to those in C.

Startup Code
------------

Unlike with some runtime systems, it shouldn't be necessary (unless there are bugs) to use a Fortran main program unit to ensure the runtime---specifically the I/O system---is initialized.

However, to use the g77 intrinsics GETARG and IARGC, either the main routine from the libg2c library must be used, or the f_setarg routine (new as of egcs version 1.1 and g77 version 0.5.23) must be called with the appropriate argc and argv arguments prior to the program calling GETARG or IARGC.

To provide more flexibility for mixed-language programming involving g77 while allowing for shared libraries, as of egcs version 1.1 and g77 version 0.5.23, g77's main routine in libg2c does the following, in order:

 1. Calls f_setarg with the incoming argc and argv arguments, in the same order as for main itself.

     This sets up the command-line environment for GETARG and IARGC.

 2. Calls f_setsig (with no arguments).

     This sets up the signaling and exception environment.

 3. Calls f_init (with no arguments).

     This initializes the I/O environment, though that should not be necessary, as all I/O functions in libf2c are believed to call f_init automatically, if necessary.

     (A future version of g77 might skip this explicit step, to speed up normal exit of a program.)

 4. Arranges for f_exit to be called (with no arguments) when the program exits.

     This ensures that the I/O environment is properly shut down before the program exits normally. Otherwise, output buffers might not be fully flushed, scratch files might not be deleted, and so on.

     The simple way main does this is to call f_exit itself after calling MAIN__ (in the next step).

     However, this does not catch the cases where the program might call exit directly, instead of using the EXIT intrinsic (implemented as exit_ in libf2c).

     So, main attempts to use the operating environment's onexit or atexit facility, if available, to cause f_exit to be called automatically upon any invocation of exit.

 5. Calls MAIN__ (with no arguments).

     This starts executing the Fortran main program unit for the application. (Both g77 and f2c currently compile a main program unit so that its global name is MAIN__.)

 6. If no onexit or atexit is provided by the system, calls f_exit.

 7. Calls exit with a zero argument, to signal a successful program termination.

 8. Returns a zero value to the caller, to signal a successful program termination, in case exit doesn't exit on the system.

All of the above names are C extern names, i.e. not mangled.

When using the main procedure provided by g77 without a Fortran main program unit, you need to provide MAIN__ as the entry point for your C code. (Make sure you link the object file that defines that entry point with the rest of your program.)

To provide your own main procedure in place of g77's, make sure you specify the object file defining that procedure before -lg2c on the g77 command line. Since the -lg2c option is implicitly provided, this is usually straightforward. (Use the --verbose option to see how and where g77 implicitly adds -lg2c in a command line that will link the program. Feel free to specify -lg2c explicitly, as appropriate.)

However, when providing your own main, make sure you perform the appropriate tasks in the appropriate order. For example, if your main does not call f_setarg, make sure the rest of your application does not call GETARG or IARGC.

And, if your main fails to ensure that f_exit is called upon program exit, some files might end up incompletely written, some scratch files might be left lying around, and some existing files being written might be left with old data not properly truncated at the end.

Note that, generally, the g77 operating environment does not depend on a procedure named MAIN__ actually being called prior to any other g77-compiled code. That is, MAIN__ does not, itself, set up any important operating-environment characteristics upon which other code might depend. This might change in future versions of g77, with appropriate notification in the release notes.

For more information, consult the source code for the above routines. These are in path-libf2c/libF77/, named main.c, setarg.c, setsig.c, getarg_.c, and iargc_.c.

Also, the file path-g77/com.c contains the code g77 uses to open-code (inline) references to IARGC.

Debugging and Interfacing
*************************

GNU Fortran currently generates code that is object-compatible with the f2c converter. Also, it avoids limitations in the current GBE, such as the inability to generate a procedure with multiple entry points, by generating code that is structured differently (in terms of procedure names, scopes, arguments, and so on) than might be expected.

As a result, writing code in other languages that calls on, is called by, or shares in-memory data with g77-compiled code generally requires some understanding of the way g77 compiles code for various constructs.

Similarly, using a debugger to debug g77-compiled code, even if that debugger supports native Fortran debugging, generally requires this sort of information.

This section describes some of the basic information on how g77 compiles code for constructs involving interfaces to other languages and to debuggers.

Caution: Much or all of this information pertains to only the current release of g77, sometimes even to using certain compiler options with g77 (such as -fno-f2c). Do not write code that depends on this information without clearly marking said code as nonportable and subject to review for every new release of g77. This information is provided primarily to make debugging of code generated by this particular release of g77 easier for the user, and partly to make writing (generally nonportable) interface code easier. Both of these activities require tracking changes in new version of g77 as they are installed, because new versions can change the behaviors described in this section.

Main Program Unit (PROGRAM)
===========================

When g77 compiles a main program unit, it gives it the public procedure name MAIN__. The libg2c library has the actual main() procedure as is typical of C-based environments, and it is this procedure that performs some initial start-up activity and then calls MAIN__.

Generally, g77 and libg2c are designed so that you need not include a main program unit written in Fortran in your program---it can be written in C or some other language. Especially for I/O handling, this is the case, although g77 version 0.5.16 includes a bug fix for libg2c that solved a problem with using the OPEN statement as the first Fortran I/O activity in a program without a Fortran main program unit.

However, if you don't intend to use g77 (or f2c) to compile your main program unit---that is, if you intend to compile a main() procedure using some other language---you should carefully examine the code for main() in libg2c, found in the source file path-libf2c/libF77/main.c, to see what kinds of things might need to be done by your main() in order to provide the Fortran environment your Fortran code is expecting.

For example, libg2c's main() sets up the information used by the IARGC and GETARG intrinsics. Bypassing libg2c's main() without providing a substitute for this activity would mean that invoking IARGC and GETARG would produce undefined results.

When debugging, one implication of the fact that main(), which is the place where the debugged program ``starts'' from the debugger's point of view, is in libg2c is that you won't be starting your Fortran program at a point you recognize as your Fortran code.

The standard way to get around this problem is to set a break point (a one-time, or temporary, break point will do) at the entrance to MAIN__, and then run the program. A convenient way to do so is to add the gdb command

     tbreak MAIN__

to the file .gdbinit in the directory in which you're debugging (using gdb).

After doing this, the debugger will see the current execution point of the program as at the beginning of the main program unit of your program.

Of course, if you really want to set a break point at some other place in your program and just start the program running, without first breaking at MAIN__, that should work fine.

Procedures (SUBROUTINE and FUNCTION)
====================================

Currently, g77 passes arguments via reference---specifically, by passing a pointer to the location in memory of a variable, array, array element, a temporary location that holds the result of evaluating an expression, or a temporary or permanent location that holds the value of a constant.

Procedures that accept CHARACTER arguments are implemented by g77 so that each CHARACTER argument has two actual arguments.

The first argument occupies the expected position in the argument list and has the user-specified name. This argument is a pointer to an array of characters, passed by the caller.

The second argument is appended to the end of the user-specified calling sequence and is named __g77_length_X, where X is the user-specified name. This argument is of the C type ftnlen (see path-libf2c/g2c.h.in for information on that type) and is the number of characters the caller has allocated in the array pointed to by the first argument.

A procedure will ignore the length argument if X is not declared CHARACTER*(*), because for other declarations, it knows the length. Not all callers necessarily ``know'' this, however, which is why they all pass the extra argument.

The contents of the CHARACTER argument are specified by the address passed in the first argument (named after it). The procedure can read or write these contents as appropriate.

When more than one CHARACTER argument is present in the argument list, the length arguments are appended in the order the original arguments appear. So CALL FOO('HI','THERE') is implemented in C as foo("hi","there",2,5);, ignoring the fact that g77 does not provide the trailing null bytes on the constant strings (f2c does provide them, but they are unnecessary in a Fortran environment, and you should not expect them to be there).

Note that the above information applies to CHARACTER variables and arrays only. It does not apply to external CHARACTER functions or to intrinsic CHARACTER functions. That is, no second length argument is passed to FOO in this case:

     CHARACTER X
     EXTERNAL X
     CALL FOO(X)

Nor does FOO expect such an argument in this case:

     SUBROUTINE FOO(X)
     CHARACTER X
     EXTERNAL X

Because of this implementation detail, if a program has a bug such that there is disagreement as to whether an argument is a procedure, and the type of the argument is CHARACTER, subtle symptoms might appear.

Functions (FUNCTION and RETURN)
===============================

g77 handles in a special way functions that return the following types:

  * CHARACTER

  * COMPLEX

  * REAL(KIND=1)

For CHARACTER, g77 implements a subroutine (a C function returning void) with two arguments prepended: __g77_result, which the caller passes as a pointer to a char array expected to hold the return value, and __g77_length, which the caller passes as an ftnlen value specifying the length of the return value as declared in the calling program. For CHARACTER*(*), the called function uses __g77_length to determine the size of the array that __g77_result points to; otherwise, it ignores that argument.

For COMPLEX, when -ff2c is in force, g77 implements a subroutine with one argument prepended: __g77_result, which the caller passes as a pointer to a variable of the type of the function. The called function writes the return value into this variable instead of returning it as a function value. When -fno-f2c is in force, g77 implements a COMPLEX function as gcc's __complex__ float or __complex__ double function (or an emulation thereof, when -femulate-complex is in effect), returning the result of the function in the same way as gcc would.

For REAL(KIND=1), when -ff2c is in force, g77 implements a function that actually returns REAL(KIND=2) (typically C's double type). When -fno-f2c is in force, REAL(KIND=1) functions return float.

Names
=====

Fortran permits each implementation to decide how to represent names as far as how they're seen in other contexts, such as debuggers and when interfacing to other languages, and especially as far as how casing is handled.

External names---names of entities that are public, or ``accessible'', to all modules in a program---normally have an underscore (_) appended by g77, to generate code that is compatible with f2c. External names include names of Fortran things like common blocks, external procedures (subroutines and functions, but not including statement functions, which are internal procedures), and entry point names.

However, use of the -fno-underscoring option disables this kind of transformation of external names (though inhibiting the transformation certainly improves the chances of colliding with incompatible externals written in other languages---but that might be intentional.

When -funderscoring is in force, any name (external or local) that already has at least one underscore in it is implemented by g77 by appending two underscores. (This second underscore can be disabled via the -fno-second-underscore option.) External names are changed this way for f2c compatibility. Local names are changed this way to avoid collisions with external names that are different in the source code---f2c does the same thing, but there's no compatibility issue there except for user expectations while debugging.

For example:

     Max_Cost = 0

Here, a user would, in the debugger, refer to this variable using the name max_cost__ (or MAX_COST__ or Max_Cost__, as described below). (We hope to improve g77 in this regard in the future---don't write scripts depending on this behavior! Also, consider experimenting with the -fno-underscoring option to try out debugging without having to massage names by hand like this.)

g77 provides a number of command-line options that allow the user to control how case mapping is handled for source files. The default is the traditional UNIX model for Fortran compilers---names are mapped to lower case. Other command-line options can be specified to map names to upper case, or to leave them exactly as written in the source file.

For example:

     Foo = 9.436

Here, it is normally the case that the variable assigned will be named foo. This would be the name to enter when using a debugger to access the variable.

However, depending on the command-line options specified, the name implemented by g77 might instead be FOO or even Foo, thus affecting how debugging is done.

Also:

     Call Foo

This would normally call a procedure that, if it were in a separate C program, be defined starting with the line:

     void foo_()

However, g77 command-line options could be used to change the casing of names, resulting in the name FOO_ or Foo_ being given to the procedure instead of foo_, and the -fno-underscoring option could be used to inhibit the appending of the underscore to the name.

Common Blocks (COMMON)
======================

g77 names and lays out COMMON areas the same way f2c does, for compatibility with f2c.

Local Equivalence Areas (EQUIVALENCE)
=====================================

g77 treats storage-associated areas involving a COMMON block as explained in the section on common blocks.

A local EQUIVALENCE area is a collection of variables and arrays connected to each other in any way via EQUIVALENCE, none of which are listed in a COMMON statement.

(Note: g77 version 0.5.18 and earlier chose the name for X using a different method when more than one name was in the list of names of entities placed at the beginning of the array. Though the documentation specified that the first name listed in the EQUIVALENCE statements was chosen for X, g77 in fact chose the name using a method that was so complicated, it seemed easier to change it to an alphabetical sort than to describe the previous method in the documentation.)

Complex Variables (COMPLEX)
===========================

As of 0.5.20, g77 defaults to handling COMPLEX types (and related intrinsics, constants, functions, and so on) in a manner that makes direct debugging involving these types in Fortran language mode difficult.

Essentially, g77 implements these types using an internal construct similar to C's struct, at least as seen by the gcc back end.

Currently, the back end, when outputting debugging info with the compiled code for the assembler to digest, does not detect these struct types as being substitutes for Fortran complex. As a result, the Fortran language modes of debuggers such as gdb see these types as C struct types, which they might or might not support.

Until this is fixed, switch to C language mode to work with entities of COMPLEX type and then switch back to Fortran language mode afterward. (In gdb, this is accomplished via set lang c and either set lang fortran or set lang auto.)

Arrays (DIMENSION)
==================

Fortran uses ``column-major ordering'' in its arrays. This differs from other languages, such as C, which use ``row-major ordering''. The difference is that, with Fortran, array elements adjacent to each other in memory differ in the first subscript instead of the last; A(5,10,20) immediately follows A(4,10,20), whereas with row-major ordering it would follow A(5,10,19).

This consideration affects not only interfacing with and debugging Fortran code, it can greatly affect how code is designed and written, especially when code speed and size is a concern.

Fortran also differs from C, a popular language for interfacing and to support directly in debuggers, in the way arrays are treated. In C, arrays are single-dimensional and have interesting relationships to pointers, neither of which is true for Fortran. As a result, dealing with Fortran arrays from within an environment limited to C concepts can be challenging.

For example, accessing the array element A(5,10,20) is easy enough in Fortran (use A(5,10,20)), but in C some difficult machinations are needed. First, C would treat the A array as a single-dimension array. Second, C does not understand low bounds for arrays as does Fortran. Third, C assumes a low bound of zero (0), while Fortran defaults to a low bound of one (1) and can supports an arbitrary low bound. Therefore, calculations must be done to determine what the C equivalent of A(5,10,20) would be, and these calculations require knowing the dimensions of A.

For DIMENSION A(2:11,21,0:29), the calculation of the offset of A(5,10,20) would be:

       (5-2)
     + (10-1)*(11-2+1)
     + (20-0)*(11-2+1)*(21-1+1)
     = 4293

So the C equivalent in this case would be a[4293].

When using a debugger directly on Fortran code, the C equivalent might not work, because some debuggers cannot understand the notion of low bounds other than zero.  However, unlike f2c, g77 does inform the GBE that a multi-dimensional array (like A in the above example) is really multi-dimensional, rather than a single-dimensional array, so at least the dimensionality of the array is preserved.

Debuggers that understand Fortran should have no trouble with nonzero low bounds, but for non-Fortran debuggers, especially C debuggers, the above example might have a C equivalent of a[4305]. This calculation is arrived at by eliminating the subtraction of the lower bound in the first parenthesized expression on each line---that is, for (5-2) substitute (5), for (10-1) substitute (10), and for (20-0) substitute (20). Actually, the implication of this can be that the expression *(&a[2][1][0] + 4293) works fine, but that a[20][10][5] produces the equivalent of *(&a[0][0][0] + 4305) because of the missing lower bounds.

Come to think of it, perhaps the behavior is due to the debugger internally compensating for the lower bounds by offsetting the base address of a, leaving &a set lower, in this case, than &a[2][1][0] (the address of its first element as identified by subscripts equal to the corresponding lower bounds).

You know, maybe nobody really needs to use arrays.

Adjustable Arrays (DIMENSION)
=============================

Adjustable and automatic arrays in Fortran require the implementation (in this case, the g77 compiler) to ``memorize'' the expressions that dimension the arrays each time the procedure is invoked. This is so that subsequent changes to variables used in those expressions, made during execution of the procedure, do not have any effect on the dimensions of those arrays.

For example:

     REAL ARRAY(5)
     DATA ARRAY/5*2/
     CALL X(ARRAY, 5)
     END
     SUBROUTINE X(A, N)
     DIMENSION A(N)
     N = 20
     PRINT *, N, A
     END

Here, the implementation should, when running the program, print something like:

     20   2.  2.  2.  2.  2.

Note that this shows that while the value of N was successfully changed, the size of the A array remained at 5 elements.

To support this, g77 generates code that executes before any user code (and before the internally generated computed GOTO to handle alternate entry points, as described below) that evaluates each (nonconstant) expression in the list of subscripts for an array, and saves the result of each such evaluation to be used when determining the size of the array (instead of re-evaluating the expressions).

So, in the above example, when X is first invoked, code is executed that copies the value of N to a temporary. And that same temporary serves as the actual high bound for the single dimension of the A array (the low bound being the constant 1). Since the user program cannot (legitimately) change the value of the temporary during execution of the procedure, the size of the array remains constant during each invocation.

For alternate entry points, the code g77 generates takes into account the possibility that a dummy adjustable array is not actually passed to the actual entry point being invoked at that time. In that case, the public procedure implementing the entry point passes to the master private procedure implementing all the code for the entry points a NULL pointer where a pointer to that adjustable array would be expected. The g77-generated code doesn't attempt to evaluate any of the expressions in the subscripts for an array if the pointer to that array is NULL at run time in such cases. (Don't depend on this particular implementation by writing code that purposely passes NULL pointers where the callee expects adjustable arrays, even if you know the callee won't reference the arrays---nor should you pass NULL pointers for any dummy arguments used in calculating the bounds of such arrays or leave undefined any values used for that purpose in COMMON---because the way g77 implements these things might change in the future!)

Alternate Entry Points (ENTRY)
==============================

The GBE does not understand the general concept of alternate entry points as Fortran provides via the ENTRY statement. g77 gets around this by using an approach to compiling procedures having at least one ENTRY statement that is almost identical to the approach used by f2c. (An alternate approach could be used that would probably generate faster, but larger, code that would also be a bit easier to debug.)

Information on how g77 implements ENTRY is provided for those trying to debug such code. The choice of implementation seems unlikely to affect code (compiled in other languages) that interfaces to such code.

g77 compiles exactly one public procedure for the primary entry point of a procedure plus each ENTRY point it specifies, as usual. That is, in terms of the public interface, there is no difference between

     SUBROUTINE X
     END
     SUBROUTINE Y
     END

and:

     SUBROUTINE X
     ENTRY Y
     END

The difference between the above two cases lies in the code compiled for the X and Y procedures themselves, plus the fact that, for the second case, an extra internal procedure is compiled.

For every Fortran procedure with at least one ENTRY statement, g77 compiles an extra procedure named __g77_masterfun_X, where X is the name of the primary entry point (which, in the above case, using the standard compiler options, would be x_ in C).

This extra procedure is compiled as a private procedure---that is, a procedure not accessible by name to separately compiled modules. It contains all the code in the program unit, including the code for the primary entry point plus for every entry point. (The code for each public procedure is quite short, and explained later.)

The extra procedure has some other interesting characteristics.

The argument list for this procedure is invented by g77. It contains a single integer argument named __g77_which_entrypoint, passed by value (as in Fortran's %VAL() intrinsic), specifying the entry point index---0 for the primary entry point, 1 for the first entry point (the first ENTRY statement encountered), 2 for the second entry point, and so on.

It also contains, for functions returning CHARACTER and (when -ff2c is in effect) COMPLEX functions, and for functions returning different types among the ENTRY statements (e.g. REAL FUNCTION R() containing ENTRY I()), an argument named __g77_result that is expected at run time to contain a pointer to where to store the result of the entry point. For CHARACTER functions, this storage area is an array of the appropriate number of characters; for COMPLEX functions, it is the appropriate area for the return type; for multiple-return-type functions, it is a union of all the supported return types (which cannot include CHARACTER, since combining CHARACTER and non-CHARACTER return types via ENTRY in a single function is not supported by g77).

For CHARACTER functions, the __g77_result argument is followed by yet another argument named __g77_length that, at run time, specifies the caller's expected length of the returned value. Note that only CHARACTER*(*) functions and entry points actually make use of this argument, even though it is always passed by all callers of public CHARACTER functions (since the caller does not generally know whether such a function is CHARACTER*(*) or whether there are any other callers that don't have that information).

The rest of the argument list is the union of all the arguments specified for all the entry points (in their usual forms, e.g. CHARACTER arguments have extra length arguments, all appended at the end of this list). This is considered the ``master list'' of arguments.

The code for this procedure has, before the code for the first executable statement, code much like that for the following Fortran statement:

            GOTO (100000,100001,100002), __g77_which_entrypoint
     100000 ...code for primary entry point...
     100001 ...code immediately following first ENTRY statement...
     100002 ...code immediately following second ENTRY statement...

(Note that invalid Fortran statement labels and variable names are used in the above example to highlight the fact that it represents code generated by the g77 internals, not code to be written by the user.)

It is this code that, when the procedure is called, picks which entry point to start executing.

Getting back to the public procedures (x and Y in the original example), those procedures are fairly simple. Their interfaces are just like they would be if they were self-contained procedures (without ENTRY), of course, since that is what the callers expect. Their code consists of simply calling the private procedure, described above, with the appropriate extra arguments (the entry point index, and perhaps a pointer to a multiple-type- return variable, local to the public procedure, that contains all the supported returnable non-character types). For arguments that are not listed for a given entry point that are listed for other entry points, and therefore that are in the ``master list'' for the private procedure, null pointers (in C, the NULL macro) are passed. Also, for entry points that are part of a multiple-type- returning function, code is compiled after the call of the private procedure to extract from the multi-type union the appropriate result, depending on the type of the entry point in question, returning that result to the original caller.

When debugging a procedure containing alternate entry points, you can either set a break point on the public procedure itself (e.g. a break point on X or Y) or on the private procedure that contains most of the pertinent code (e.g. __g77_masterfun_X). If you do the former, you should use the debugger's command to ``step into'' the called procedure to get to the actual code; with the latter approach, the break point leaves you right at the actual code, skipping over the public entry point and its call to the private procedure (unless you have set a break point there as well, of course).

Further, the list of dummy arguments that is visible when the private procedure is active is going to be the expanded version of the list for whichever particular entry point is active, as explained above, and the way in which return values are handled might well be different from how they would be handled for an equivalent single-entry function.

Alternate Returns (SUBROUTINE and RETURN)
=========================================

Subroutines with alternate returns (e.g. SUBROUTINE X(*) and CALL X(*50)) are implemented by g77 as functions returning the C int type. The actual alternate-return arguments are omitted from the calling sequence. Instead, the caller uses the return value to do a rough equivalent of the Fortran computed-GOTO statement, as in GOTO (50), X() in the example above (where X is quietly declared as an INTEGER(KIND=1) function), and the callee just returns whatever integer is specified in the RETURN statement for the subroutine For example, RETURN 1 is implemented as X = 1 followed by RETURN in C, and RETURN by itself is X = 0 and RETURN).

Assigned Statement Labels (ASSIGN and GOTO)
===========================================

For portability to machines where a pointer (such as to a label, which is how g77 implements ASSIGN and its relatives, the assigned-GOTO and assigned-FORMAT-I/O statements) is wider (bitwise) than an INTEGER(KIND=1), g77 uses a different memory location to hold the ASSIGNed value of a variable than it does the numerical value in that variable, unless the variable is wide enough (can hold enough bits).

In particular, while g77 implements

     I = 10

as, in C notation, i = 10;, it implements

     ASSIGN 10 TO I

as, in GNU's extended C notation (for the label syntax), __g77_ASSIGN_I = &&L10; (where L10 is just a massaging of the Fortran label 10 to make the syntax C-like; g77 doesn't actually generate the name L10 or any other name like that, since debuggers cannot access labels anyway).

While this currently means that an ASSIGN statement does not overwrite the numeric contents of its target variable, do not write any code depending on this feature. g77 has already changed this implementation across versions and might do so in the future. This information is provided only to make debugging Fortran programs compiled with the current version of g77 somewhat easier. If there's no debugger-visible variable named __g77_ASSIGN_I in a program unit that does ASSIGN 10 TO I, that probably means g77 has decided it can store the pointer to the label directly into I itself.

See Ugly Assigned Labels, for information on a command-line option to force g77 to use the same storage for both normal and assigned-label uses of a variable.

Run-time Library Errors
=======================

The libg2c library currently has the following table to relate error code numbers, returned in IOSTAT= variables, to messages. This information should, in future versions of this document, be expanded upon to include detailed descriptions of each message.

In line with good coding practices, any of the numbers in the list below should not be directly written into Fortran code you write. Instead, make a separate INCLUDE file that defines PARAMETER names for them, and use those in your code, so you can more easily change the actual numbers in the future.

The information below is culled from the definition of F_err in f/runtime/libI77/err.c in the g77 source tree.

     100: "error in format"
     101: "illegal unit number"
     102: "formatted io not allowed"
     103: "unformatted io not allowed"
     104: "direct io not allowed"
     105: "sequential io not allowed"
     106: "can't backspace file"
     107: "null file name"
     108: "can't stat file"
     109: "unit not connected"
     110: "off end of record"
     111: "truncation failed in endfile"
     112: "incomprehensible list input"
     113: "out of free space"
     114: "unit not connected"
     115: "read unexpected character"
     116: "bad logical input field"
     117: "bad variable type"
     118: "bad namelist name"
     119: "variable not in namelist"
     120: "no end record"
     121: "variable count incorrect"
     122: "subscript for scalar variable"
     123: "invalid array section"
     124: "substring out of bounds"
     125: "subscript out of bounds"
     126: "can't read file"
     127: "can't write file"
     128: "'new' file exists"
     129: "can't append to file"
     130: "non-positive record number"
     131: "I/O started while already doing I/O"

Collected Fortran Wisdom
************************

Most users of g77 can be divided into two camps:

  * Those writing new Fortran code to be compiled by g77.

  * Those using g77 to compile existing, ``legacy'' code.

Users writing new code generally understand most of the necessary aspects of Fortran to write ``mainstream'' code, but often need help deciding how to handle problems, such as the construction of libraries containing BLOCK DATA.

Users dealing with ``legacy'' code sometimes don't have much experience with Fortran, but believe that the code they're compiling already works when compiled by other compilers (and might not understand why, as is sometimes the case, it doesn't work when compiled by g77).

The following information is designed to help users do a better job coping with existing, ``legacy'' Fortran code, and with writing new code as well.

Advantages Over f2c
===================

Without f2c, g77 would have taken much longer to do and probably not been as good for quite a while. Sometimes people who notice how much g77 depends on, and documents encouragement to use, f2c ask why g77 was created if f2c already existed.

This section gives some basic answers to these questions, though it is not intended to be comprehensive.

Language Extensions
-------------------

g77 offers several extensions to FORTRAN 77 language that f2c doesn't:

  * Automatic arrays

  * CYCLE and EXIT

  * Construct names

  * SELECT CASE

  * KIND= and LEN= notation

  * Semicolon as statement separator

  * Constant expressions in FORMAT statements (such as FORMAT(I<J>), where J is a PARAMETER named constant)

  * MvBits intrinsic

  * libU77 (Unix-compatibility) library, with routines known to compiler as intrinsics (so they work even when compiler options are used to change the interfaces used by Fortran routines)

g77 also implements iterative DO loops so that they work even in the presence of certain ``extreme'' inputs, unlike f2c. See Loops.

However, f2c offers a few that g77 doesn't, such as:

  * Intrinsics in PARAMETER statements

  * Array bounds expressions (such as REAL M(N(2)))

  * AUTOMATIC statement

It is expected that g77 will offer some or all of these missing features at some time in the future.

Diagnostic Abilities
--------------------

g77 offers better diagnosis of problems in FORMAT statements. f2c doesn't, for example, emit any diagnostic for FORMAT(XZFAJG10324), leaving that to be diagnosed, at run time, by the libf2c run-time library.

Compiler Options
----------------

g77 offers compiler options that f2c doesn't, most of which are designed to more easily accommodate legacy code:

  * Two that control the automatic appending of extra underscores to external names

  * One that allows dollar signs ($) in symbol names

  * A variety that control acceptance of various ``ugly'' constructs

  * Several that specify acceptable use of upper and lower case in the source code

  * Many that enable, disable, delete, or hide groups of intrinsics

  * One to specify the length of fixed-form source lines (normally 72)

  * One to specify the the source code is written in Fortran-90-style free-form

However, f2c offers a few that g77 doesn't, like an option to have REAL default to REAL*8. It is expected that g77 will offer all of the missing options pertinent to being a Fortran compiler at some time in the future.

Compiler Speed
--------------

Saving the steps of writing and then rereading C code is a big reason why g77 should be able to compile code much faster than using f2c in conjunction with the equivalent invocation of gcc.

However, due to g77's youth, lots of self-checking is still being performed. As a result, this improvement is as yet unrealized (though the potential seems to be there for quite a big speedup in the future). It is possible that, as of version 0.5.18, g77 is noticeably faster compiling many Fortran source files than using f2c in conjunction with gcc.

Program Speed
-------------

g77 has the potential to better optimize code than f2c, even when gcc is used to compile the output of f2c, because f2c must necessarily translate Fortran into a somewhat lower-level language (C) that cannot preserve all the information that is potentially useful for optimization, while g77 can gather, preserve, and transmit that information directly to the GBE.

For example, g77 implements ASSIGN and assigned GOTO using direct assignment of pointers to labels and direct jumps to labels, whereas f2c maps the assigned labels to integer values and then uses a C switch statement to encode the assigned GOTO statements.

However, as is typical, theory and reality don't quite match, at least not in all cases, so it is still the case that f2c plus gcc can generate code that is faster than g77.

Version 0.5.18 of g77 offered default settings and options, via patches to the gcc back end, that allow for better program speed, though some of these improvements also affected the performance of programs translated by f2c and then compiled by g77's version of gcc.

Version 0.5.20 of g77 offers further performance improvements, at least one of which (alias analysis) is not generally applicable to f2c (though f2c could presumably be changed to also take advantage of this new capability of the gcc back end, assuming this is made available in an upcoming release of gcc).

Ease of Debugging
-----------------

Because g77 compiles directly to assembler code like gcc, instead of translating to an intermediate language (C) as does f2c, support for debugging can be better for g77 than f2c.

However, although g77 might be somewhat more ``native'' in terms of debugging support than f2c plus gcc, there still are a lot of things ``not quite right''. Many of the important ones should be resolved in the near future.

For example, g77 doesn't have to worry about reserved names like f2c does. Given FOR = WHILE, f2c must necessarily translate this to something other than for = while;, because C reserves those words.

However, g77 does still uses things like an extra level of indirection for ENTRY-laden procedures---in this case, because the back end doesn't yet support multiple entry points.

Another example is that, given

     COMMON A, B
     EQUIVALENCE (B, C)

the g77 user should be able to access the variables directly, by name, without having to traverse C-like structures and unions, while f2c is unlikely to ever offer this ability (due to limitations in the C language).

Yet another example is arrays. g77 represents them to the debugger using the same ``dimensionality'' as in the source code, while f2c must necessarily convert them all to one-dimensional arrays to fit into the confines of the C language. However, the level of support offered by debuggers for interactive Fortran-style access to arrays as compiled by g77 can vary widely. In some cases, it can actually be an advantage that f2c converts everything to widely supported C semantics.

In fairness, g77 could do many of the things f2c does to get things working at least as well as f2c---for now, the developers prefer making g77 work the way they think it is supposed to, and finding help improving the other products (the back end of gcc; gdb; and so on) to get things working properly.

Character and Hollerith Constants
---------------------------------

To avoid the extensive hassle that would be needed to avoid this, f2c uses C character constants to encode character and Hollerith constants. That means a constant like 'HELLO' is translated to "hello" in C, which further means that an extra null byte is present at the end of the constant. This null byte is superfluous.

g77 does not generate such null bytes. This represents significant savings of resources, such as on systems where /dev/null or /dev/zero represent bottlenecks in the systems' performance, because g77 simply asks for fewer zeros from the operating system than f2c. (Avoiding spurious use of zero bytes, each byte typically have eight zero bits, also reduces the liabilities in case Microsoft's rumored patent on the digits 0 and 1 is upheld.)

Block Data and Libraries
========================

To ensure that block data program units are linked, especially a concern when they are put into libraries, give each one a name (as in BLOCK DATA FOO) and make sure there is an EXTERNAL FOO statement in every program unit that uses any common block initialized by the corresponding BLOCK DATA. g77 currently compiles a BLOCK DATA as if it were a SUBROUTINE, that is, it generates an actual procedure having the appropriate name. The procedure does nothing but return immediately if it happens to be called. For EXTERNAL FOO, where FOO is not otherwise referenced in the same program unit, g77 assumes there exists a BLOCK DATA FOO in the program and ensures that by generating a reference to it so the linker will make sure it is present. (Specifically, g77 outputs in the data section a static pointer to the external name FOO.)

The implementation g77 currently uses to make this work is one of the few things not compatible with f2c as currently shipped. f2c currently does nothing with EXTERNAL FOO except issue a warning that FOO is not otherwise referenced, and, for BLOCK DATA FOO, f2c doesn't generate a dummy procedure with the name FOO. The upshot is that you shouldn't mix f2c and g77 in this particular case. If you use f2c to compile BLOCK DATA FOO, then any g77-compiled program unit that says EXTERNAL FOO will result in an unresolved reference when linked. If you do the opposite, then FOO might not be linked in under various circumstances (such as when FOO is in a library, or you're using a ``clever'' linker---so clever, it produces a broken program with little or no warning by omitting initializations of global data because they are contained in unreferenced procedures).

The changes you make to your code to make g77 handle this situation, however, appear to be a widely portable way to handle it. That is, many systems permit it (as they should, since the FORTRAN 77 standard permits EXTERNAL FOO when FOO is a block data program unit), and of the ones that might not link BLOCK DATA FOO under some circumstances, most of them appear to do so once EXTERNAL FOO is present in the appropriate program units.

Here is the recommended approach to modifying a program containing a program unit such as the following:

     BLOCK DATA FOO
     COMMON /VARS/ X, Y, Z
     DATA X, Y, Z / 3., 4., 5. /
     END

If the above program unit might be placed in a library module, then ensure that every program unit in every program that references that particular COMMON area uses the EXTERNAL statement to force the area to be initialized.

For example, change a program unit that starts with

     INTEGER FUNCTION CURX()
     COMMON /VARS/ X, Y, Z
     CURX = X
     END

so that it uses the EXTERNAL statement, as in:

     INTEGER FUNCTION CURX()
     COMMON /VARS/ X, Y, Z
     EXTERNAL FOO
     CURX = X
     END

That way, CURX is compiled by g77 (and many other compilers) so that the linker knows it must include FOO, the BLOCK DATA program unit that sets the initial values for the variables in VAR, in the executable program.

Loops
=====

The meaning of a DO loop in Fortran is precisely specified in the Fortran standard...and is quite different from what many programmers might expect.

In particular, Fortran iterative DO loops are implemented as if the number of trips through the loop is calculated before the loop is entered.

The number of trips for a loop is calculated from the START, END, and INCREMENT values specified in a statement such as:

     DO ITER = START, END, INCREMENT

The trip count is evaluated using a fairly simple formula based on the three values following the = in the statement, and it is that trip count that is effectively decremented during each iteration of the loop. If, at the beginning of an iteration of the loop, the trip count is zero or negative, the loop terminates. The per-loop-iteration modifications to ITER are not related to determining whether to terminate the loop.

There are two important things to remember about the trip count:

  * It can be negative, in which case it is treated as if it was zero---meaning the loop is not executed at all.

  * The type used to calculate the trip count is the same type as ITER, but the final calculation, and thus the type of the trip count itself, always is INTEGER(KIND=1).

These two items mean that there are loops that cannot be written in straightforward fashion using the Fortran DO.

For example, on a system with the canonical 32-bit two's-complement implementation of INTEGER(KIND=1), the following loop will not work:

     DO I = -2000000000, 2000000000

Although the START and END values are well within the range of INTEGER(KIND=1), the trip count is not. The expected trip count is 40000000001, which is outside the range of INTEGER(KIND=1) on many systems.

Instead, the above loop should be constructed this way:

     I = -2000000000
     DO
       IF (I .GT. 2000000000) EXIT
       ...
       I = I + 1
     END DO

The simple DO construct and the EXIT statement (used to leave the innermost loop) are F90 features that g77 supports.

Some Fortran compilers have buggy implementations of DO, in that they don't follow the standard. They implement DO as a straightforward translation to what, in C, would be a for statement. Instead of creating a temporary variable to hold the trip count as calculated at run time, these compilers use the iteration variable ITER to control whether the loop continues at each iteration.

The bug in such an implementation shows up when the trip count is within the range of the type of ITER, but the magnitude of ABS(END) + ABS(INCR) exceeds that range.  For example:

     DO I = 2147483600, 2147483647

A loop started by the above statement will work as implemented by g77, but the use, by some compilers, of a more C-like implementation akin to

     for (i = 2147483600; i <= 2147483647; ++i)

produces a loop that does not terminate, because i can never be greater than 2147483647, since incrementing it beyond that value overflows i, setting it to -2147483648. This is a large, negative number that still is less than 2147483647.

Another example of unexpected behavior of DO involves using a nonintegral iteration variable ITER, that is, a REAL variable. Consider the following program:

           DATA BEGIN, END, STEP /.1, .31, .007/
           DO 10 R = BEGIN, END, STEP
              IF (R .GT. END) PRINT *, R, ' .GT. ', END, '!!'
              PRINT *,R
     10    CONTINUE
           PRINT *,'LAST = ',R
           IF (R .LE. END) PRINT *, R, ' .LE. ', END, '!!'
           END

A C-like view of DO would hold that the two ``exclamatory'' PRINT statements are never executed. However, this is the output of running the above program as compiled by g77 on a GNU/Linux ix86 system:

      .100000001
      .107000001
      .114
      .120999999
      ...
      .289000005
      .296000004
      .303000003
     LAST =   .310000002
      .310000002 .LE.   .310000002!!

Note that one of the two checks in the program turned up an apparent violation of the programmer's expectation---yet, the loop is correctly implemented by g77, in that it has 30 iterations. This trip count of 30 is correct when evaluated using the floating-point representations for the BEGIN, END, and INCR values (.1, .31, .007) on GNU/Linux ix86 are used. On other systems, an apparently more accurate trip count of 31 might result, but, nevertheless, g77 is faithfully following the Fortran standard, and the result is not what the author of the sample program above apparently expected. (Such other systems might, for different values in the DATA statement, violate the other programmer's expectation, for example.)

Due to this combination of imprecise representation of floating-point values and the often-misunderstood interpretation of DO by standard-conforming compilers such as g77, use of DO loops with REAL iteration variables is not recommended. Such use can be caught by specifying -Wsurprising. See Warning Options, for more information on this option.

Working Programs
================

Getting Fortran programs to work in the first place can be quite a challenge---even when the programs already work on other systems, or when using other compilers.

g77 offers some facilities that might be useful for tracking down bugs in such programs.

Not My Type
-----------

A fruitful source of bugs in Fortran source code is use, or mis-use, of Fortran's implicit-typing feature, whereby the type of a variable, array, or function is determined by the first character of its name.

Simple cases of this include statements like LOGX=9.227, without a statement such as REAL LOGX. In this case, LOGX is implicitly given INTEGER(KIND=1) type, with the result of the assignment being that it is given the value 9.

More involved cases include a function that is defined starting with a statement like DOUBLE PRECISION FUNCTION IPS(...). Any caller of this function that does not also declare IPS as type DOUBLE PRECISION (or, in GNU Fortran, REAL(KIND=2)) is likely to assume it returns INTEGER, or some other type, leading to invalid results or even program crashes.

The -Wimplicit option might catch failures to properly specify the types of variables, arrays, and functions in the code.

However, in code that makes heavy use of Fortran's implicit-typing facility, this option might produce so many warnings about cases that are working, it would be hard to find the one or two that represent bugs. This is why so many experienced Fortran programmers strongly recommend widespread use of the IMPLICIT NONE statement, despite it not being standard FORTRAN 77, to completely turn off implicit typing. (g77 supports IMPLICIT NONE, as do almost all FORTRAN 77 compilers.)

Note that -Wimplicit catches only implicit typing of names. It does not catch implicit typing of expressions such as X**(2/3). Such expressions can be buggy as well---in fact, X**(2/3) is equivalent to X**0, due to the way Fortran expressions are given types and then evaluated. (In this particular case, the programmer probably wanted X**(2./3.).)

Variables Assumed To Be Zero
----------------------------

Many Fortran programs were developed on systems that provided automatic initialization of all, or some, variables and arrays to zero. As a result, many of these programs depend, sometimes inadvertently, on this behavior, though to do so violates the Fortran standards.

You can ask g77 for this behavior by specifying the -finit-local-zero option when compiling Fortran code. (You might want to specify -fno-automatic as well, to avoid code-size inflation for non-optimized compilations.)

Note that a program that works better when compiled with the -finit-local-zero option is almost certainly depending on a particular system's, or compiler's, tendency to initialize some variables to zero. It might be worthwhile finding such cases and fixing them, using techniques such as compiling with the -O -Wuninitialized options using g77.

Variables Assumed To Be Saved
-----------------------------

Many Fortran programs were developed on systems that saved the values of all, or some, variables and arrays across procedure calls. As a result, many of these programs depend, sometimes inadvertently, on being able to assign a value to a variable, perform a RETURN to a calling procedure, and, upon subsequent invocation, reference the previously assigned variable to obtain the value.

They expect this despite not using the SAVE statement to specify that the value in a variable is expected to survive procedure returns and calls. Depending on variables and arrays to retain values across procedure calls without using SAVE to require it violates the Fortran standards.

You can ask g77 to assume SAVE is specified for all relevant (local) variables and arrays by using the -fno-automatic option.

Note that a program that works better when compiled with the -fno-automatic option is almost certainly depending on not having to use the SAVE statement as required by the Fortran standard. It might be worthwhile finding such cases and fixing them, using techniques such as compiling with the -O -Wuninitialized options using g77.

Unwanted Variables
------------------

The -Wunused option can find bugs involving implicit typing, sometimes more easily than using -Wimplicit in code that makes heavy use of implicit typing. An unused variable or array might indicate that the spelling for its declaration is different from that of its intended uses.

Other than cases involving typos, unused variables rarely indicate actual bugs in a program. However, investigating such cases thoroughly has, on occasion, led to the discovery of code that had not been completely written---where the programmer wrote declarations as needed for the whole algorithm, wrote some or even most of the code for that algorithm, then got distracted and forgot that the job was not complete.

Unused Arguments
----------------

As with unused variables, It is possible that unused arguments to a procedure might indicate a bug. Compile with -W -Wunused option to catch cases of unused arguments.

Note that -W also enables warnings regarding overflow of floating-point constants under certain circumstances.

Surprising Interpretations of Code
----------------------------------

The -Wsurprising option can help find bugs involving expression evaluation or in the way DO loops with non-integral iteration variables are handled. Cases found by this option might indicate a difference of interpretation between the author of the code involved, and a standard-conforming compiler such as g77. Such a difference might produce actual bugs.

In any case, changing the code to explicitly do what the programmer might have expected it to do, so g77 and other compilers are more likely to follow the programmer's expectations, might be worthwhile, especially if such changes make the program work better.

Aliasing Assumed To Work
------------------------

The -falias-check, -fargument-alias, -fargument-noalias, and -fno-argument-noalias-global options, introduced in version 0.5.20 and g77's version 2.7.2.2.f.2 of gcc, were withdrawn as of g77 version 0.5.23 due to their not being supported by gcc version 2.8.

These options control the assumptions regarding aliasing (overlapping) of writes and reads to main memory (core) made by the gcc back end.

The information below still is useful, but applies to only those versions of g77 that support the alias analysis implied by support for these options.

These options are effective only when compiling with -O (specifying any level other than -O0) or with -falias-check.

The default for Fortran code is -fargument-noalias-global. (The default for C code and code written in other C-based languages is -fargument-alias. These defaults apply regardless of whether you use g77 or gcc to compile your code.)

Note that, on some systems, compiling with -fforce-addr in effect can produce more optimal code when the default aliasing options are in effect (and when optimization is enabled).

If your program is not working when compiled with optimization, it is possible it is violating the Fortran standards (77 and 90) by relying on the ability to ``safely'' modify variables and arrays that are aliased, via procedure calls, to other variables and arrays, without using EQUIVALENCE to explicitly set up this kind of aliasing.

(The FORTRAN 77 standard's prohibition of this sort of overlap, generally referred to therein as ``storage association'', appears in Sections 15.9.3.6. This prohibition allows implementations, such as g77, to, for example, implement the passing of procedures and even values in COMMON via copy operations into local, perhaps more efficiently accessed temporaries at entry to a procedure, and, where appropriate, via copy operations back out to their original locations in memory at exit from that procedure, without having to take into consideration the order in which the local copies are updated by the code, among other things.)

To test this hypothesis, try compiling your program with the -fargument-alias option, which causes the compiler to revert to assumptions essentially the same as made by versions of g77 prior to 0.5.20.

If the program works using this option, that strongly suggests that the bug is in your program. Finding and fixing the bug(s) should result in a program that is more standard-conforming and that can be compiled by g77 in a way that results in a faster executable.

(You might want to try compiling with -fargument-noalias, a kind of half-way point, to see if the problem is limited to aliasing between dummy arguments and COMMON variables---this option assumes that such aliasing is not done, while still allowing aliasing among dummy arguments.)

An example of aliasing that is invalid according to the standards is shown in the following program, which might not produce the expected results when executed:

     I = 1
     CALL FOO(I, I)
     PRINT *, I
     END

     SUBROUTINE FOO(J, K)
     J = J + K
     K = J * K
     PRINT *, J, K
     END

The above program attempts to use the temporary aliasing of the J and K arguments in FOO to effect a pathological behavior---the simultaneous changing of the values of both J and K when either one of them is written.

The programmer likely expects the program to print these values:

     2  4
     4

However, since the program is not standard-conforming, an implementation's behavior when running it is undefined, because subroutine FOO modifies at least one of the arguments, and they are aliased with each other. (Even if one of the assignment statements was deleted, the program would still violate these rules. This kind of on-the-fly aliasing is permitted by the standard only when none of the aliased items are defined, or written, while the aliasing is in effect.)

As a practical example, an optimizing compiler might schedule the J = part of the second line of FOO after the reading of J and K for the J * K expression, resulting in the following output:

     2  2
     2

Essentially, compilers are promised (by the standard and, therefore, by programmers who write code they claim to be standard-conforming) that if they cannot detect aliasing via static analysis of a single program unit's EQUIVALENCE and COMMON statements, no such aliasing exists. In such cases, compilers are free to assume that an assignment to one variable will not change the value of another variable, allowing it to avoid generating code to re-read the value of the other variable, to re-schedule reads and writes, and so on, to produce a faster executable.

The same promise holds true for arrays (as seen by the called procedure)---an element of one dummy array cannot be aliased with, or overlap, any element of another dummy array or be in a COMMON area known to the procedure.

(These restrictions apply only when the procedure defines, or writes to, one of the aliased variables or arrays.)

Unfortunately, there is no way to find all possible cases of violations of the prohibitions against aliasing in Fortran code. Static analysis is certainly imperfect, as is run-time analysis, since neither can catch all violations. (Static analysis can catch all likely violations, and some that might never actually happen, while run-time analysis can catch only those violations that actually happen during a particular run. Neither approach can cope with programs mixing Fortran code with routines written in other languages, however.)

Currently, g77 provides neither static nor run-time facilities to detect any cases of this problem, although other products might. Run-time facilities are more likely to be offered by future versions of g77, though patches improving g77 so that it provides either form of detection are welcome.

Output Assumed To Flush
-----------------------

For several versions prior to 0.5.20, g77 configured its version of the libf2c run-time library so that one of its configuration macros, ALWAYS_FLUSH, was defined.

This was done as a result of a belief that many programs expected output to be flushed to the operating system (under UNIX, via the fflush() library call) with the result that errors, such as disk full, would be immediately flagged via the relevant ERR= and IOSTAT= mechanism.

Because of the adverse effects this approach had on the performance of many programs, g77 no longer configures libf2c (now named libg2c in its g77 incarnation) to always flush output.

If your program depends on this behavior, either insert the appropriate CALL FLUSH statements, or modify the sources to the libg2c, rebuild and reinstall g77, and relink your programs with the modified library.

(Ideally, libg2c would offer the choice at run-time, so that a compile-time option to g77 or f2c could result in generating the appropriate calls to flushing or non-flushing library routines.)

Some Fortran programs require output (writes) to be flushed to the operating system (under UNIX, via the fflush() library call) so that errors, such as disk full, are immediately flagged via the relevant ERR= and IOSTAT= mechanism, instead of such errors being flagged later as subsequent writes occur, forcing the previously written data to disk, or when the file is closed.

Essentially, the difference can be viewed as synchronous error reporting (immediate flagging of errors during writes) versus asynchronous, or, more precisely, buffered error reporting (detection of errors might be delayed).

libg2c supports flagging write errors immediately when it is built with the ALWAYS_FLUSH macro defined. This results in a libg2c that runs slower, sometimes quite a bit slower, under certain circumstances---for example, accessing files via the networked file system NFS---but the effect can be more reliable, robust file I/O.

If you know that Fortran programs requiring this level of precision of error reporting are to be compiled using the version of g77 you are building, you might wish to modify the g77 source tree so that the version of libg2c is built with the ALWAYS_FLUSH macro defined, enabling this behavior.

To do this, find this line in path-libf2c/f2c.h in your g77 source tree:

     /* #define ALWAYS_FLUSH */

Remove the leading /* , so the line begins with #define, and the trailing  */.

Then build or rebuild g77 as appropriate.

Large File Unit Numbers
-----------------------

If your program crashes at run time with a message including the text illegal unit number, that probably is a message from the run-time library, libg2c.

The message means that your program has attempted to use a file unit number that is out of the range accepted by libg2c. Normally, this range is 0 through 99, and the high end of the range is controlled by a libg2c source-file macro named MXUNIT.

If you can easily change your program to use unit numbers in the range 0 through 99, you should do so.

As distributed, whether as part of f2c or g77, libf2c accepts file unit numbers only in the range 0 through 99. For example, a statement such as WRITE (UNIT=100) causes a run-time crash in libf2c, because the unit number, 100, is out of range.

If you know that Fortran programs at your installation require the use of unit numbers higher than 99, you can change the value of the MXUNIT macro, which represents the maximum unit number, to an appropriately higher value.

To do this, edit the file path-libf2c/libI77/fio.h in your g77 source tree, changing the following line:

     #define MXUNIT 100

Change the line so that the value of MXUNIT is defined to be at least one greater than the maximum unit number used by the Fortran programs on your system.

(For example, a program that does WRITE (UNIT=255) would require MXUNIT set to at least 256 to avoid crashing.)

Then build or rebuild g77 as appropriate.

Note: Changing this macro has no effect on other limits your system might place on the number of files open at the same time. That is, the macro might allow a program to do WRITE (UNIT=100), but the library and operating system underlying libf2c might disallow it if many other files have already been opened (via OPEN or implicitly via READ, WRITE, and so on). Information on how to increase these other limits should be found in your system's documentation.

Floating-point precision
------------------------

If your program depends on exact IEEE 754 floating-point handling it may help on some systems---specifically x86 or m68k hardware---to use the -ffloat-store option or to reset the precision flag on the floating-point unit. See Optimize Options.

However, it might be better simply to put the FPU into double precision mode and not take the performance hit of -ffloat-store.  On x86 and m68k GNU systems you can do this with a technique similar to that for turning on floating-point exceptions (see Floating-point Exception Handling). The control word could be set to double precision by some code like this one:

     #include <fpu_control.h>
     {
       fpu_control_t cw = (_FPU_DEFAULT & ~_FPU_EXTENDED) | _FPU_DOUBLE;
       _FPU_SETCW(cw);
     }

(It is not clear whether this has any effect on the operation of the GNU maths library, but we have no evidence of it causing trouble.)

Some targets (such as the Alpha) may need special options for full IEEE conformance. See Hardware Models and Configurations (Using the GNU Compiler Collection (GCC)).

Inconsistent Calling Sequences
------------------------------

Code containing inconsistent calling sequences in the same file is normally rejected---see GLOBALS. (Use, say, ftnchek to ensure consistency across source files. See Generating Skeletons and Prototypes with f2c.)

Mysterious errors, which may appear to be code generation problems, can appear specifically on the x86 architecture with some such inconsistencies.  On x86 hardware, floating-point return values of functions are placed on the floating-point unit's register stack, not the normal stack.  Thus calling a REAL or DOUBLE PRECISION FUNCTION as some other sort of procedure, or vice versa, scrambles the floating-point stack.  This may break unrelated code executed later.  Similarly if, say, external C routines are written incorrectly.

Overly Convenient Command-line Options
======================================

These options should be used only as a quick-and-dirty way to determine how well your program will run under different compilation models without having to change the source. Some are more problematic than others, depending on how portable and maintainable you want the program to be (and, of course, whether you are allowed to change it at all is crucial).

You should not continue to use these command-line options to compile a given program, but rather should make changes to the source code:

-finit-local-zero
     (This option specifies that any uninitialized local variables and arrays have default initialization to binary zeros.)

     Many other compilers do this automatically, which means lots of Fortran code developed with those compilers depends on it.

     It is safer (and probably would produce a faster program) to find the variables and arrays that need such initialization and provide it explicitly via DATA, so that -finit-local-zero is not needed.

     Consider using -Wuninitialized (which requires -O) to find likely candidates, but do not specify -finit-local-zero or -fno-automatic, or this technique won't work.

-fno-automatic
     (This option specifies that all local variables and arrays are to be treated as if they were named in SAVE statements.)

     Many other compilers do this automatically, which means lots of Fortran code developed with those compilers depends on it.

     The effect of this is that all non-automatic variables and arrays are made static, that is, not placed on the stack or in heap storage. This might cause a buggy program to appear to work better. If so, rather than relying on this command-line option (and hoping all compilers provide the equivalent one), add SAVE statements to some or all program unit sources, as appropriate. Consider using -Wuninitialized (which requires -O) to find likely candidates, but do not specify -finit-local-zero or -fno-automatic, or this technique won't work.

     The default is -fautomatic, which tells g77 to try and put variables and arrays on the stack (or in fast registers) where possible and reasonable. This tends to make programs faster.

     Note: Automatic variables and arrays are not affected by this option. These are variables and arrays that are necessarily automatic, either due to explicit statements, or due to the way they are declared. Examples include local variables and arrays not given the SAVE attribute in procedures declared RECURSIVE, and local arrays declared with non-constant bounds (automatic arrays). Currently, g77 supports only automatic arrays, not RECURSIVE procedures or other means of explicitly specifying that variables or arrays are automatic.

-fGROUP-intrinsics-hide
     Change the source code to use EXTERNAL for any external procedure that might be the name of an intrinsic. It is easy to find these using -fGROUP-intrinsics-disable.

Faster Programs
===============

Aside from the usual gcc options, such as -O, -ffast-math, and so on, consider trying some of the following approaches to speed up your program (once you get it working).

Aligned Data
------------

On some systems, such as those with Pentium Pro CPUs, programs that make heavy use of REAL(KIND=2) (DOUBLE PRECISION) might run much slower than possible due to the compiler not aligning these 64-bit values to 64-bit boundaries in memory. (The effect also is present, though to a lesser extent, on the 586 (Pentium) architecture.)

The Intel x86 architecture generally ensures that these programs will work on all its implementations, but particular implementations (such as Pentium Pro) perform better with more strict alignment. (Such behavior isn't unique to the Intel x86 architecture.) Other architectures might demand 64-bit alignment of 64-bit data.

There are a variety of approaches to use to address this problem:

  * Order your COMMON and EQUIVALENCE areas such that the variables and arrays with the widest alignment guidelines come first.

     For example, on most systems, this would mean placing COMPLEX(KIND=2), REAL(KIND=2), and INTEGER(KIND=2) entities first, followed by REAL(KIND=1), INTEGER(KIND=1), and LOGICAL(KIND=1) entities, then INTEGER(KIND=6) entities, and finally CHARACTER and INTEGER(KIND=3) entities.

     The reason to use such placement is it makes it more likely that your data will be aligned properly, without requiring you to do detailed analysis of each aggregate (COMMON and EQUIVALENCE) area.

     Specifically, on systems where the above guidelines are appropriate, placing CHARACTER entities before REAL(KIND=2) entities can work just as well, but only if the number of bytes occupied by the CHARACTER entities is divisible by the recommended alignment for REAL(KIND=2).

     By ordering the placement of entities in aggregate areas according to the simple guidelines above, you avoid having to carefully count the number of bytes occupied by each entity to determine whether the actual alignment of each subsequent entity meets the alignment guidelines for the type of that entity.

     If you don't ensure correct alignment of COMMON elements, the compiler may be forced by some systems to violate the Fortran semantics by adding padding to get DOUBLE PRECISION data properly aligned. If the unfortunate practice is employed of overlaying different types of data in the COMMON block, the different variants of this block may become misaligned with respect to each other. Even if your platform doesn't require strict alignment, COMMON should be laid out as above for portability. (Unfortunately the FORTRAN 77 standard didn't anticipate this possible requirement, which is compiler-independent on a given platform.)

  * Use the (x86-specific) -malign-double option when compiling programs for the Pentium and Pentium Pro architectures (called 586 and 686 in the gcc configuration subsystem). The warning about this in the gcc manual isn't generally relevant to Fortran, but using it will force COMMON to be padded if necessary to align DOUBLE PRECISION data.

     When DOUBLE PRECISION data is forcibly aligned in COMMON by g77 due to specifying -malign-double, g77 issues a warning about the need to insert padding.

     In this case, each and every program unit that uses the same COMMON area must specify the same layout of variables and their types for that area and be compiled with -malign-double as well. g77 will issue warnings in each case, but as long as every program unit using that area is compiled with the same warnings, the resulting object files should work when linked together unless the program makes additional assumptions about COMMON area layouts that are outside the scope of the FORTRAN 77 standard, or uses EQUIVALENCE or different layouts in ways that assume no padding is ever inserted by the compiler.

  * Ensure that crt0.o or crt1.o on your system guarantees a 64-bit aligned stack for main(). The recent one from GNU (glibc2) will do this on x86 systems, but we don't know of any other x86 setups where it will be right. Read your system's documentation to determine if it is appropriate to upgrade to a more recent version to obtain the optimal alignment.

Progress is being made on making this work ``out of the box'' on future versions of g77, gcc, and some of the relevant operating systems (such as GNU/Linux).

Prefer Automatic Uninitialized Variables
----------------------------------------

If you're using -fno-automatic already, you probably should change your code to allow compilation with -fautomatic (the default), to allow the program to run faster.

Similarly, you should be able to use -fno-init-local-zero (the default) instead of -finit-local-zero. This is because it is rare that every variable affected by these options in a given program actually needs to be so affected.

For example, -fno-automatic, which effectively SAVEs every local non-automatic variable and array, affects even things like DO iteration variables, which rarely need to be SAVEd, and this often reduces run-time performances. Similarly, -fno-init-local-zero forces such variables to be initialized to zero---when SAVEd (such as when -fno-automatic), this by itself generally affects only startup time for a program, but when not SAVEd, it can slow down the procedure every time it is called.

See Overly Convenient Command-Line Options, for information on the -fno-automatic and -finit-local-zero options and how to convert their use into selective changes in your own code.

Avoid f2c Compatibility
-----------------------

If you aren't linking with any code compiled using f2c, try using the -fno-f2c option when compiling all the code in your program. (Note that libf2c is not an example of code that is compiled using f2c---it is compiled by a C compiler, typically gcc.)

Use Submodel Options
--------------------

Using an appropriate -m option to generate specific code for your CPU may be worthwhile, though it may mean the executable won't run on other versions of the CPU that don't support the same instruction set. See Hardware Models and Configurations (Using the GNU Compiler Collection (GCC)).  For instance on an x86 system the compiler might have been built---as shown by g77 -v---for the target i386-pc-linux-gnu, i.e. an i386 CPU.  In that case to generate code best optimized for a Pentium you could use the option -march=pentium.

For recent CPUs that don't have explicit support in the released version of gcc, it might still be possible to get improvements with certain -m options.

-fomit-frame-pointer can help performance on x86 systems and others.  It will, however, inhibit debugging on the systems on which it is not turned on anyway by -O.

Known Causes of Trouble with GNU Fortran
****************************************

This section describes known problems that affect users of GNU Fortran. Most of these are not GNU Fortran bugs per se---if they were, we would fix them. But the result for a user might be like the result of a bug.

Some of these problems are due to bugs in other software, some are missing features that are too much work to add, and some are places where people's opinions differ as to what is best.

(Note that some of this portion of the manual is lifted directly from the gcc manual, with minor modifications to tailor it to users of g77. Anytime a bug seems to have more to do with the gcc portion of g77, see Known Causes of Trouble with GCC (Using the GNU Compiler Collection (GCC)).)

Bugs Not In GNU Fortran
=======================

These are bugs to which the maintainers often have to reply, ``but that isn't a bug in g77...''. Some of these already are fixed in new versions of other software; some still need to be fixed; some are problems with how g77 is installed or is being used; some are the result of bad hardware that causes software to misbehave in sometimes bizarre ways; some just cannot be addressed at this time until more is known about the problem.

Please don't re-report these bugs to the g77 maintainers---if you must remind someone how important it is to you that the problem be fixed, talk to the people responsible for the other products identified below, but preferably only after you've tried the latest versions of those products. The g77 maintainers have their hands full working on just fixing and improving g77, without serving as a clearinghouse for all bugs that happen to affect g77 users.

See Collected Fortran Wisdom, for information on behavior of Fortran programs, and the programs that compile them, that might be thought to indicate bugs.

Signal 11 and Friends
---------------------

A whole variety of strange behaviors can occur when the software, or the way you are using the software, stresses the hardware in a way that triggers hardware bugs. This might seem hard to believe, but it happens frequently enough that there exist documents explaining in detail what the various causes of the problems are, what typical symptoms look like, and so on.

Generally these problems are referred to in this document as ``signal 11'' crashes, because the Linux kernel, running on the most popular hardware (the Intel x86 line), often stresses the hardware more than other popular operating systems. When hardware problems do occur under GNU/Linux on x86 systems, these often manifest themselves as ``signal 11'' problems, as illustrated by the following diagnostic:

     sh# g77 myprog.f
     gcc: Internal compiler error: program f771 got fatal signal 11
     sh#

It is very important to remember that the above message is not the only one that indicates a hardware problem, nor does it always indicate a hardware problem.

In particular, on systems other than those running the Linux kernel, the message might appear somewhat or very different, as it will if the error manifests itself while running a program other than the g77 compiler. For example, it will appear somewhat different when running your program, when running Emacs, and so on.

How to cope with such problems is well beyond the scope of this manual.

However, users of Linux-based systems (such as GNU/Linux) should review http://www.bitwizard.nl/sig11/, a source of detailed information on diagnosing hardware problems, by recognizing their common symptoms.

Users of other operating systems and hardware might find this reference useful as well. If you know of similar material for another hardware/software combination, please let us know so we can consider including a reference to it in future versions of this manual.

Cannot Link Fortran Programs
----------------------------

On some systems, perhaps just those with out-of-date (shared?) libraries, unresolved-reference errors happen when linking g77-compiled programs (which should be done using g77).

If this happens to you, try appending -lc to the command you use to link the program, e.g. g77 foo.f -lc. g77 already specifies -lg2c -lm when it calls the linker, but it cannot also specify -lc because not all systems have a file named libc.a.

It is unclear at this point whether there are legitimately installed systems where -lg2c -lm is insufficient to resolve code produced by g77.

If your program doesn't link due to unresolved references to names like _main, make sure you're using the g77 command to do the link, since this command ensures that the necessary libraries are loaded by specifying -lg2c -lm when it invokes the gcc command to do the actual link. (Use the -v option to discover more about what actually happens when you use the g77 and gcc commands.)

Also, try specifying -lc as the last item on the g77 command line, in case that helps.

Large Common Blocks
-------------------

On some older GNU/Linux systems, programs with common blocks larger than 16MB cannot be linked without some kind of error message being produced.

This is a bug in older versions of ld, fixed in more recent versions of binutils, such as version 2.6.

Debugger Problems
-----------------

There are some known problems when using gdb on code compiled by g77. Inadequate investigation as of the release of 0.5.16 results in not knowing which products are the culprit, but gdb-4.14 definitely crashes when, for example, an attempt is made to print the contents of a COMPLEX(KIND=2) dummy array, on at least some GNU/Linux machines, plus some others. Attempts to access assumed-size arrays are also known to crash recent versions of gdb. (gdb's Fortran support was done for a different compiler and isn't properly compatible with g77.)

NeXTStep Problems
-----------------

Developers of Fortran code on NeXTStep (all architectures) have to watch out for the following problem when writing programs with large, statically allocated (i.e. non-stack based) data structures (common blocks, saved arrays).

Due to the way the native loader (/bin/ld) lays out data structures in virtual memory, it is very easy to create an executable wherein the __DATA segment overlaps (has addresses in common) with the UNIX STACK segment.

This leads to all sorts of trouble, from the executable simply not executing, to bus errors. The NeXTStep command line tool ebadexec points to the problem as follows:

     % /bin/ebadexec a.out
     /bin/ebadexec: __LINKEDIT segment (truncated address = 0x3de000
     rounded size = 0x2a000) of executable file: a.out overlaps with UNIX
     STACK segment (truncated address = 0x400000 rounded size =
     0x3c00000) of executable file: a.out

(In the above case, it is the __LINKEDIT segment that overlaps the stack segment.)

This can be cured by assigning the __DATA segment (virtual) addresses beyond the stack segment. A conservative estimate for this is from address 6000000 (hexadecimal) onwards---this has always worked for me [Toon Moene]:

     % g77 -segaddr __DATA 6000000 test.f
     % ebadexec a.out
     ebadexec: file: a.out appears to be executable
     %

Browsing through path-g77/Makefile.in, you will find that the f771 program itself also has to be linked with these flags---it has large statically allocated data structures. (Version 0.5.18 reduces this somewhat, but probably not enough.)

(The above item was contributed by Toon Moene (toon@moene.indiv.nluug.nl).)

Stack Overflow
--------------

g77 code might fail at runtime (probably with a ``segmentation violation'') due to overflowing the stack. This happens most often on systems with an environment that provides substantially more heap space (for use when arbitrarily allocating and freeing memory) than stack space.

Often this can be cured by increasing or removing your shell's limit on stack usage, typically using limit stacksize (in csh and derivatives) or ulimit -s (in sh and derivatives).

Increasing the allowed stack size might, however, require changing some operating system or system configuration parameters.

You might be able to work around the problem by compiling with the -fno-automatic option to reduce stack usage, probably at the expense of speed.

g77, on most machines, puts many variables and arrays on the stack where possible, and can be configured (by changing FFECOM_sizeMAXSTACKITEM in path-g77/com.c) to force smaller-sized entities into static storage (saving on stack space) or permit larger-sized entities to be put on the stack (which can improve run-time performance, as it presents more opportunities for the GBE to optimize the generated code).

Note: Putting more variables and arrays on the stack might cause problems due to system-dependent limits on stack size. Also, the value of FFECOM_sizeMAXSTACKITEM has no effect on automatic variables and arrays. See But-bugs, for more information. Note: While libg2c places a limit on the range of Fortran file-unit numbers, the underlying library and operating system might impose different kinds of limits. For example, some systems limit the number of files simultaneously open by a running program. Information on how to increase these limits should be found in your system's documentation.

However, if your program uses large automatic arrays (for example, has declarations like REAL A(N) where A is a local array and N is a dummy or COMMON variable that can have a large value), neither use of -fno-automatic, nor changing the cut-off point for g77 for using the stack, will solve the problem by changing the placement of these large arrays, as they are necessarily automatic.

g77 currently provides no means to specify that automatic arrays are to be allocated on the heap instead of the stack. So, other than increasing the stack size, your best bet is to change your source code to avoid large automatic arrays. Methods for doing this currently are outside the scope of this document.

(Note: If your system puts stack and heap space in the same memory area, such that they are effectively combined, then a stack overflow probably indicates a program that is either simply too large for the system, or buggy.)

Nothing Happens
---------------

It is occasionally reported that a ``simple'' program, such as a ``Hello, World!'' program, does nothing when it is run, even though the compiler reported no errors, despite the program containing nothing other than a simple PRINT statement.

This most often happens because the program has been compiled and linked on a UNIX system and named test, though other names can lead to similarly unexpected run-time behavior on various systems.

Essentially this problem boils down to giving your program a name that is already known to the shell you are using to identify some other program, which the shell continues to execute instead of your program when you invoke it via, for example:

     sh# test
     sh#

Under UNIX and many other system, a simple command name invokes a searching mechanism that might well not choose the program located in the current working directory if there is another alternative (such as the test command commonly installed on UNIX systems).

The reliable way to invoke a program you just linked in the current directory under UNIX is to specify it using an explicit pathname, as in:

     sh# ./test
      Hello, World!
     sh#

Users who encounter this problem should take the time to read up on how their shell searches for commands, how to set their search path, and so on. The relevant UNIX commands to learn about include man, info (on GNU systems), setenv (or set and env), which, and find.

Strange Behavior at Run Time
----------------------------

g77 code might fail at runtime with ``segmentation violation'', ``bus error'', or even something as subtle as a procedure call overwriting a variable or array element that it is not supposed to touch.

These can be symptoms of a wide variety of actual bugs that occurred earlier during the program's run, but manifested themselves as visible problems some time later.

Overflowing the bounds of an array---usually by writing beyond the end of it---is one of two kinds of bug that often occurs in Fortran code. (Compile your code with the -fbounds-check option to catch many of these kinds of errors at program run time.)

The other kind of bug is a mismatch between the actual arguments passed to a procedure and the dummy arguments as declared by that procedure.

Both of these kinds of bugs, and some others as well, can be difficult to track down, because the bug can change its behavior, or even appear to not occur, when using a debugger.

That is, these bugs can be quite sensitive to data, including data representing the placement of other data in memory (that is, pointers, such as the placement of stack frames in memory).

g77 now offers the ability to catch and report some of these problems at compile, link, or run time, such as by generating code to detect references to beyond the bounds of most arrays (except assumed-size arrays), and checking for agreement between calling and called procedures. Future improvements are likely to be made in the procedure-mismatch area, at least.

In the meantime, finding and fixing the programming bugs that lead to these behaviors is, ultimately, the user's responsibility, as difficult as that task can sometimes be.

One runtime problem that has been observed might have a simple solution. If a formatted WRITE produces an endless stream of spaces, check that your program is linked against the correct version of the C library. The configuration process takes care to account for your system's normal libc not being ANSI-standard, which will otherwise cause this behavior. If your system's default library is ANSI-standard and you subsequently link against a non-ANSI one, there might be problems such as this one.

Specifically, on Solaris2 systems, avoid picking up the BSD library from /usr/ucblib.

Floating-point Errors
---------------------

Some programs appear to produce inconsistent floating-point results compiled by g77 versus by other compilers.

Often the reason for this behavior is the fact that floating-point values are represented on almost all Fortran systems by approximations, and these approximations are inexact even for apparently simple values like 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9, 1.1, and so on. Most Fortran systems, including all current ports of g77, use binary arithmetic to represent these approximations.

Therefore, the exact value of any floating-point approximation as manipulated by g77-compiled code is representable by adding some combination of the values 1.0, 0.5, 0.25, 0.125, and so on (just keep dividing by two) through the precision of the fraction (typically around 23 bits for REAL(KIND=1), 52 for REAL(KIND=2)), then multiplying the sum by a integral power of two (in Fortran, by 2**N) that typically is between -127 and +128 for REAL(KIND=1) and -1023 and +1024 for REAL(KIND=2), then multiplying by -1 if the number is negative.

So, a value like 0.2 is exactly represented in decimal---since it is a fraction, 2/10, with a denominator that is compatible with the base of the number system (base 10). However, 2/10 cannot be represented by any finite number of sums of any of 1.0, 0.5, 0.25, and so on, so 0.2 cannot be exactly represented in binary notation.

(On the other hand, decimal notation can represent any binary number in a finite number of digits. Decimal notation cannot do so with ternary, or base-3, notation, which would represent floating-point numbers as sums of any of 1/1, 1/3, 1/9, and so on. After all, no finite number of decimal digits can exactly represent 1/3. Fortunately, few systems use ternary notation.)

Moreover, differences in the way run-time I/O libraries convert between these approximations and the decimal representation often used by programmers and the programs they write can result in apparent differences between results that do not actually exist, or exist to such a small degree that they usually are not worth worrying about.

For example, consider the following program:

     PRINT *, 0.2
     END

When compiled by g77, the above program might output 0.20000003, while another compiler might produce a executable that outputs 0.2.

This particular difference is due to the fact that, currently, conversion of floating-point values by the libg2c library, used by g77, handles only double-precision values.

Since 0.2 in the program is a single-precision value, it is converted to double precision (still in binary notation) before being converted back to decimal. The conversion to binary appends binary zero digits to the original value---which, again, is an inexact approximation of 0.2---resulting in an approximation that is much less exact than is connoted by the use of double precision.

(The appending of binary zero digits has essentially the same effect as taking a particular decimal approximation of 1/3, such as 0.3333333, and appending decimal zeros to it, producing 0.33333330000000000. Treating the resulting decimal approximation as if it really had 18 or so digits of valid precision would make it seem a very poor approximation of 1/3.)

As a result of converting the single-precision approximation to double precision by appending binary zeros, the conversion of the resulting double-precision value to decimal produces what looks like an incorrect result, when in fact the result is inexact, and is probably no less inaccurate or imprecise an approximation of 0.2 than is produced by other compilers that happen to output the converted value as ``exactly'' 0.2. (Some compilers behave in a way that can make them appear to retain more accuracy across a conversion of a single-precision constant to double precision. See Context-Sensitive Constants, to see why this practice is illusory and even dangerous.)

Note that a more exact approximation of the constant is computed when the program is changed to specify a double-precision constant:

     PRINT *, 0.2D0
     END

Future versions of g77 and/or libg2c might convert single-precision values directly to decimal, instead of converting them to double precision first. This would tend to result in output that is more consistent with that produced by some other Fortran implementations.

A useful source of information on floating-point computation is David Goldberg, `What Every Computer Scientist Should Know About Floating-Point Arithmetic', Computing Surveys, 23, March 1991, pp. 5-48. An online version is available at http://docs.sun.com/.

Information related to the IEEE 754 floating-point standard by a leading light can be found at http://http.cs.berkeley.edu/%7Ewkahan/ieee754status/; see also slides from the short course referenced from http://http.cs.berkeley.edu/%7Efateman/.

The supplement to the PostScript-formatted Goldberg document, referenced above, is available in HTML format. See `Differences Among IEEE 754 Implementations' by Doug Priest. This document explores some of the issues surrounding computing of extended (80-bit) results on processors such as the x86, especially when those results are arbitrarily truncated to 32-bit or 64-bit values by the compiler as ``spills''.

(Note: g77 specifically, and gcc generally, does arbitrarily truncate 80-bit results during spills as of this writing. It is not yet clear whether a future version of the GNU compiler suite will offer 80-bit spills as an option, or perhaps even as the default behavior.)

The GNU C library provides routines for controlling the FPU, and other documentation about this.

See Floating-point precision, regarding IEEE 754 conformance.

     [file bugs.texi not included]

Missing Features
================

This section lists features we know are missing from g77, and which we want to add someday. (There is no priority implied in the ordering below.)

Better Source Model
-------------------

g77 needs to provide, as the default source-line model, a ``pure visual'' mode, where the interpretation of a source program in this mode can be accurately determined by a user looking at a traditionally displayed rendition of the program (assuming the user knows whether the program is fixed or free form).

The design should assume the user cannot tell tabs from spaces and cannot see trailing spaces on lines, but has canonical tab stops and, for fixed-form source, has the ability to always know exactly where column 72 is (since the Fortran standard itself requires this for fixed-form source).

This would change the default treatment of fixed-form source to not treat lines with tabs as if they were infinitely long---instead, they would end at column 72 just as if the tabs were replaced by spaces in the canonical way.

As part of this, provide common alternate models (Digital, f2c, and so on) via command-line options. This includes allowing arbitrarily long lines for free-form source as well as fixed-form source and providing various limits and diagnostics as appropriate.

Also, g77 should offer, perhaps even default to, warnings when characters beyond the last valid column are anything other than spaces. This would mean code with ``sequence numbers'' in columns 73 through 80 would be rejected, and there's a lot of that kind of code around, but one of the most frequent bugs encountered by new users is accidentally writing fixed-form source code into and beyond column 73. So, maybe the users of old code would be able to more easily handle having to specify, say, a -Wno-col73to80 option.

Fortran 90 Support
------------------

g77 does not support many of the features that distinguish Fortran 90 (and, now, Fortran 95) from ANSI FORTRAN 77.

Some Fortran 90 features are supported, because they make sense to offer even to die-hard users of F77. For example, many of them codify various ways F77 has been extended to meet users' needs during its tenure, so g77 might as well offer them as the primary way to meet those same needs, even if it offers compatibility with one or more of the ways those needs were met by other F77 compilers in the industry.

Still, many important F90 features are not supported, because no attempt has been made to research each and every feature and assess its viability in g77. In the meantime, users who need those features must use Fortran 90 compilers anyway, and the best approach to adding some F90 features to GNU Fortran might well be to fund a comprehensive project to create GNU Fortran 95.

Intrinsics in PARAMETER Statements
----------------------------------

g77 doesn't allow intrinsics in PARAMETER statements.

Related to this, g77 doesn't allow non-integral exponentiation in PARAMETER statements, such as PARAMETER (R=2**.25). It is unlikely g77 will ever support this feature, as doing it properly requires complete emulation of a target computer's floating-point facilities when building g77 as a cross-compiler. But, if the gcc back end is enhanced to provide such a facility, g77 will likely use that facility in implementing this feature soon afterwards.

Arbitrary Concatenation
-----------------------

g77 doesn't support arbitrary operands for concatenation in contexts where run-time allocation is required. For example:

     SUBROUTINE X(A)
     CHARACTER*(*) A
     CALL FOO(A // 'suffix')

SELECT CASE on CHARACTER Type
-----------------------------

Character-type selector/cases for SELECT CASE currently are not supported.

RECURSIVE Keyword
-----------------

g77 doesn't support the RECURSIVE keyword that F90 compilers do. Nor does it provide any means for compiling procedures designed to do recursion.

All recursive code can be rewritten to not use recursion, but the result is not pretty.

Increasing Precision/Range
--------------------------

Some compilers, such as f2c, have an option (-r8, -qrealsize=8 or similar) that provides automatic treatment of REAL entities such that they have twice the storage size, and a corresponding increase in the range and precision, of what would normally be the REAL(KIND=1) (default REAL) type. (This affects COMPLEX the same way.)

They also typically offer another option (-i8) to increase INTEGER entities so they are twice as large (with roughly twice as much range).

(There are potential pitfalls in using these options.)

g77 does not yet offer any option that performs these kinds of transformations. Part of the problem is the lack of detailed specifications regarding exactly how these options affect the interpretation of constants, intrinsics, and so on.

Until g77 addresses this need, programmers could improve the portability of their code by modifying it to not require compile-time options to produce correct results. Some free tools are available which may help, specifically in Toolpack (which one would expect to be sound) and the fortran section of the Netlib repository.

Use of preprocessors can provide a fairly portable means to work around the lack of widely portable methods in the Fortran language itself (though increasing acceptance of Fortran 90 would alleviate this problem).

Popular Non-standard Types
--------------------------

g77 doesn't fully support INTEGER*2, LOGICAL*1, and similar. In the meantime, version 0.5.18 provides rudimentary support for them.

Full Support for Compiler Types
-------------------------------

g77 doesn't support INTEGER, REAL, and COMPLEX equivalents for all applicable back-end-supported types (char, short int, int, long int, long long int, and long double). This means providing intrinsic support, and maybe constant support (using F90 syntax) as well, and, for most machines will result in automatic support of INTEGER*1, INTEGER*2, INTEGER*8, maybe even REAL*16, and so on.

Array Bounds Expressions
------------------------

g77 doesn't support more general expressions to dimension arrays, such as array element references, function references, etc.

For example, g77 currently does not accept the following:

     SUBROUTINE X(M, N)
     INTEGER N(10), M(N(2), N(1))

POINTER Statements
------------------

g77 doesn't support pointers or allocatable objects (other than automatic arrays). This set of features is probably considered just behind intrinsics in PARAMETER statements on the list of large, important things to add to g77.

In the meantime, consider using the INTEGER(KIND=7) declaration to specify that a variable must be able to hold a pointer. This construct is not portable to other non-GNU compilers, but it is portable to all machines GNU Fortran supports when g77 is used.

See Functions and Subroutines, for information on %VAL(), %REF(), and %DESCR() constructs, which are useful for passing pointers to procedures written in languages other than Fortran.

Sensible Non-standard Constructs
--------------------------------

g77 rejects things other compilers accept, like INTRINSIC SQRT,SQRT. As time permits in the future, some of these things that are easy for humans to read and write and unlikely to be intended to mean something else will be accepted by g77 (though -fpedantic should trigger warnings about such non-standard constructs).

Until g77 no longer gratuitously rejects sensible code, you might as well fix your code to be more standard-conforming and portable.

The kind of case that is important to except from the recommendation to change your code is one where following good coding rules would force you to write non-standard code that nevertheless has a clear meaning.

For example, when writing an INCLUDE file that defines a common block, it might be appropriate to include a SAVE statement for the common block (such as SAVE /CBLOCK/), so that variables defined in the common block retain their values even when all procedures declaring the common block become inactive (return to their callers).

However, putting SAVE statements in an INCLUDE file would prevent otherwise standard-conforming code from also specifying the SAVE statement, by itself, to indicate that all local variables and arrays are to have the SAVE attribute.

For this reason, g77 already has been changed to allow this combination, because although the general problem of gratuitously rejecting unambiguous and ``safe'' constructs still exists in g77, this particular construct was deemed useful enough that it was worth fixing g77 for just this case.

So, while there is no need to change your code to avoid using this particular construct, there might be other, equally appropriate but non-standard constructs, that you shouldn't have to stop using just because g77 (or any other compiler) gratuitously rejects it.

Until the general problem is solved, if you have any such construct you believe is worthwhile using (e.g. not just an arbitrary, redundant specification of an attribute), please submit a bug report with an explanation, so we can consider fixing g77 just for cases like yours.

READONLY Keyword
----------------

Support for READONLY, in OPEN statements, requires libg2c support, to make sure that CLOSE(...,STATUS='DELETE') does not delete a file opened on a unit with the READONLY keyword, and perhaps to trigger a fatal diagnostic if a WRITE or PRINT to such a unit is attempted.

Note: It is not sufficient for g77 and libg2c (its version of libf2c) to assume that READONLY does not need some kind of explicit support at run time, due to UNIX systems not (generally) needing it. g77 is not just a UNIX-based compiler!

Further, mounting of non-UNIX filesystems on UNIX systems (such as via NFS) might require proper READONLY support.

(Similar issues might be involved with supporting the SHARED keyword.)

FLUSH Statement
---------------

g77 could perhaps use a FLUSH statement that does what CALL FLUSH does, but that supports * as the unit designator (same unit as for PRINT) and accepts ERR= and/or IOSTAT= specifiers.

Expressions in FORMAT Statements
--------------------------------

g77 doesn't support FORMAT(I<J>) and the like. Supporting this requires a significant redesign or replacement of libg2c.

However, g77 does support this construct when the expression is constant (as of version 0.5.22). For example:

           PARAMETER (IWIDTH = 12)
     10    FORMAT (I<IWIDTH>)

Otherwise, at least for output (PRINT and WRITE), Fortran code making use of this feature can be rewritten to avoid it by constructing the FORMAT string in a CHARACTER variable or array, then using that variable or array in place of the FORMAT statement label to do the original PRINT or WRITE.

Many uses of this feature on input can be rewritten this way as well, but not all can. For example, this can be rewritten:

           READ 20, I
     20    FORMAT (I<J>)

However, this cannot, in general, be rewritten, especially when ERR= and END= constructs are employed:

           READ 30, J, I
     30    FORMAT (I<J>)

Explicit Assembler Code
-----------------------

g77 needs to provide some way, a la gcc, for g77 code to specify explicit assembler code.

Q Edit Descriptor
-----------------

The Q edit descriptor in FORMATs isn't supported. (This is meant to get the number of characters remaining in an input record.) Supporting this requires a significant redesign or replacement of libg2c.

A workaround might be using internal I/O or the stream-based intrinsics. See FGetC Intrinsic (subroutine).

Old-style PARAMETER Statements
------------------------------

g77 doesn't accept PARAMETER I=1. Supporting this obsolete form of the PARAMETER statement would not be particularly hard, as most of the parsing code is already in place and working.

Until time/money is spent implementing it, you might as well fix your code to use the standard form, PARAMETER (I=1) (possibly needing INTEGER I preceding the PARAMETER statement as well, otherwise, in the obsolete form of PARAMETER, the type of the variable is set from the type of the constant being assigned to it).

TYPE and ACCEPT I/O Statements
------------------------------

g77 doesn't support the I/O statements TYPE and ACCEPT. These are common extensions that should be easy to support, but also are fairly easy to work around in user code.

Generally, any TYPE fmt,list I/O statement can be replaced by PRINT fmt,list. And, any ACCEPT fmt,list statement can be replaced by READ fmt,list.

STRUCTURE, UNION, RECORD, MAP
-----------------------------

g77 doesn't support STRUCTURE, UNION, RECORD, MAP. This set of extensions is quite a bit lower on the list of large, important things to add to g77, partly because it requires a great deal of work either upgrading or replacing libg2c.

OPEN, CLOSE, and INQUIRE Keywords
---------------------------------

g77 doesn't have support for keywords such as DISP='DELETE' in the OPEN, CLOSE, and INQUIRE statements. These extensions are easy to add to g77 itself, but require much more work on libg2c.

g77 doesn't support FORM='PRINT' or an equivalent to translate the traditional `carriage control' characters in column 1 of output to use backspaces, carriage returns and the like.  However programs exist to translate them in output files (or standard output). These are typically called either fpr or asa.  You can get a version of asa from ftp://sunsite.unc.edu/pub/Linux/devel/lang/fortran for GNU systems which will probably build easily on other systems. Alternatively, fpr is in BSD distributions in various archive sites.

ENCODE and DECODE
-----------------

g77 doesn't support ENCODE or DECODE.

These statements are best replaced by READ and WRITE statements involving internal files (CHARACTER variables and arrays).

For example, replace a code fragment like

           INTEGER*1 LINE(80)
     ...
           DECODE (80, 9000, LINE) A, B, C
     ...
     9000  FORMAT (1X, 3(F10.5))

with:

           CHARACTER*80 LINE
     ...
           READ (UNIT=LINE, FMT=9000) A, B, C
     ...
     9000  FORMAT (1X, 3(F10.5))

Similarly, replace a code fragment like

           INTEGER*1 LINE(80)
     ...
           ENCODE (80, 9000, LINE) A, B, C
     ...
     9000  FORMAT (1X, 'OUTPUT IS ', 3(F10.5))

with:

           CHARACTER*80 LINE
     ...
           WRITE (UNIT=LINE, FMT=9000) A, B, C
     ...
     9000  FORMAT (1X, 'OUTPUT IS ', 3(F10.5))

It is entirely possible that ENCODE and DECODE will be supported by a future version of g77.

AUTOMATIC Statement
-------------------

g77 doesn't support the AUTOMATIC statement that f2c does.

AUTOMATIC would identify a variable or array as not being SAVE'd, which is normally the default, but which would be especially useful for code that, generally, needed to be compiled with the -fno-automatic option.

AUTOMATIC also would serve as a hint to the compiler that placing the variable or array---even a very large array--on the stack is acceptable.

AUTOMATIC would not, by itself, designate the containing procedure as recursive.

AUTOMATIC should work syntactically like SAVE, in that AUTOMATIC with no variables listed should apply to all pertinent variables and arrays (which would not include common blocks or their members).

Variables and arrays denoted as AUTOMATIC would not be permitted to be initialized via DATA or other specification of any initial values, requiring explicit initialization, such as via assignment statements.

Perhaps UNSAVE and STATIC, as strict semantic opposites to SAVE and AUTOMATIC, should be provided as well.

Suppressing Space Padding of Source Lines
-----------------------------------------

g77 should offer VXT-Fortran-style suppression of virtual spaces at the end of a source line if an appropriate command-line option is specified.

This affects cases where a character constant is continued onto the next line in a fixed-form source file, as in the following example:

     10    PRINT *,'HOW MANY
          1 SPACES?'

g77, and many other compilers, virtually extend the continued line through column 72 with spaces that become part of the character constant, but Digital Fortran normally didn't, leaving only one space between MANY and SPACES? in the output of the above statement.

Fairly recently, at least one version of Digital Fortran was enhanced to provide the other behavior when a command-line option is specified, apparently due to demand from readers of the USENET group comp.lang.fortran to offer conformance to this widespread practice in the industry. g77 should return the favor by offering conformance to Digital's approach to handling the above example.

Fortran Preprocessor
--------------------

g77 should offer a preprocessor designed specifically for Fortran to replace cpp -traditional. There are several out there worth evaluating, at least.

Such a preprocessor would recognize Hollerith constants, properly parse comments and character constants, and so on. It might also recognize, process, and thus preprocess files included via the INCLUDE directive.

Bit Operations on Floating-point Data
-------------------------------------

g77 does not allow REAL and other non-integral types for arguments to intrinsics like And, Or, and Shift.

For example, this program is rejected by g77, because the intrinsic Iand does not accept REAL arguments:

     DATA A/7.54/, B/9.112/
     PRINT *, IAND(A, B)
     END

Really Ugly Character Assignments
---------------------------------

An option such as -fugly-char should be provided to allow

     REAL*8 A1
     DATA A1 / '12345678' /

and:

     REAL*8 A1
     A1 = 'ABCDEFGH'

POSIX Standard
--------------

g77 should support the POSIX standard for Fortran.

Floating-point Exception Handling
---------------------------------

The gcc backend and, consequently, g77, currently provides no general control over whether or not floating-point exceptions are trapped or ignored. (Ignoring them typically results in NaN values being propagated in systems that conform to IEEE 754.) The behavior is normally inherited from the system-dependent startup code, though some targets, such as the Alpha, have code generation options which change the behavior.

Most systems provide some C-callable mechanism to change this; this can be invoked at startup using gcc's constructor attribute. For example, just compiling and linking the following C code with your program will turn on exception trapping for the ``common'' exceptions on a GNU system using glibc 2.2 or newer:

     #define _GNU_SOURCE 1
     #include <fenv.h>
     static void __attribute__ ((constructor))
     trapfpe ()
     {
       /* Enable some exceptions.  At startup all exceptions are masked.  */

       feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
     }

A convenient trick is to compile this something like:

     gcc -o libtrapfpe.a trapfpe.c

and then use it by adding -trapfpe to the g77 command line when linking.

Nonportable Conversions
-----------------------

g77 doesn't accept some particularly nonportable, silent data-type conversions such as LOGICAL to REAL (as in A=.FALSE., where A is type REAL), that other compilers might quietly accept.

Some of these conversions are accepted by g77 when the -fugly-logint option is specified. Perhaps it should accept more or all of them.

Large Automatic Arrays
----------------------

Currently, automatic arrays always are allocated on the stack. For situations where the stack cannot be made large enough, g77 should offer a compiler option that specifies allocation of automatic arrays in heap storage.

Support for Threads
-------------------

Neither the code produced by g77 nor the libg2c library are thread-safe, nor does g77 have support for parallel processing (other than the instruction-level parallelism available on some processors). A package such as PVM might help here.

Enabling Debug Lines
--------------------

An option such as -fdebug-lines should be provided to turn fixed-form lines beginning with D to be treated as if they began with a space, instead of as if they began with a C (as comment lines).

Better Warnings
---------------

Because of how g77 generates code via the back end, it doesn't always provide warnings the user wants. Consider:

     PROGRAM X
     PRINT *, A
     END

Currently, the above is not flagged as a case of using an uninitialized variable, because g77 generates a run-time library call that looks, to the GBE, like it might actually modify A at run time. (And, in fact, depending on the previous run-time library call, it would!)

Fixing this requires one of the following:

  * Switch to new library, libg77, that provides a more ``clean'' interface, vis-a-vis input, output, and modified arguments, so the GBE can tell what's going on.

     This would provide a pretty big performance improvement, at least theoretically, and, ultimately, in practice, for some types of code.

  * Have g77 pass a pointer to a temporary containing a copy of A, instead of to A itself. The GBE would then complain about the copy operation involving a potentially uninitialized variable.

     This might also provide a performance boost for some code, because A might then end up living in a register, which could help with inner loops.

  * Have g77 use a GBE construct similar to ADDR_EXPR but with extra information on the fact that the item pointed to won't be modified (a la const in C).

     Probably the best solution for now, but not quite trivial to implement in the general case.

Gracefully Handle Sensible Bad Code
-----------------------------------

g77 generally should continue processing for warnings and recoverable (user) errors whenever possible---that is, it shouldn't gratuitously make bad or useless code.

For example:

     INTRINSIC ZABS
     CALL FOO(ZABS)
     END

When compiling the above with -ff2c-intrinsics-disable, g77 should indeed complain about passing ZABS, but it still should compile, instead of rejecting the entire CALL statement. (Some of this is related to improving the compiler internals to improve how statements are analyzed.)

Non-standard Conversions
------------------------

-Wconversion and related should flag places where non-standard conversions are found. Perhaps much of this would be part of -Wugly*.

Non-standard Intrinsics
-----------------------

g77 needs a new option, like -Wintrinsics, to warn about use of non-standard intrinsics without explicit INTRINSIC statements for them. This would help find code that might fail silently when ported to another compiler.

Modifying DO Variable
---------------------

g77 should warn about modifying DO variables via EQUIVALENCE. (The internal information gathered to produce this warning might also be useful in setting the internal ``doiter'' flag for a variable or even array reference within a loop, since that might produce faster code someday.)

For example, this code is invalid, so g77 should warn about the invalid assignment to NOTHER:

     EQUIVALENCE (I, NOTHER)
     DO I = 1, 100
        IF (I.EQ. 10) NOTHER = 20
     END DO

Better Pedantic Compilation
---------------------------

g77 needs to support -fpedantic more thoroughly, and use it only to generate warnings instead of rejecting constructs outright. Have it warn: if a variable that dimensions an array is not a dummy or placed explicitly in COMMON (F77 does not allow it to be placed in COMMON via EQUIVALENCE); if specification statements follow statement-function-definition statements; about all sorts of syntactic extensions.

Warn About Implicit Conversions
-------------------------------

g77 needs a -Wpromotions option to warn if source code appears to expect automatic, silent, and somewhat dangerous compiler-assisted conversion of REAL(KIND=1) constants to REAL(KIND=2) based on context.

For example, it would warn about cases like this:

     DOUBLE PRECISION FOO
     PARAMETER (TZPHI = 9.435784839284958)
     FOO = TZPHI * 3D0

Invalid Use of Hollerith Constant
---------------------------------

g77 should disallow statements like RETURN 2HAB, which are invalid in both source forms (unlike RETURN (2HAB), which probably still makes no sense but at least can be reliably parsed). Fixed-form processing rejects it, but not free-form, except in a way that is a bit difficult to understand.

Dummy Array Without Dimensioning Dummy
--------------------------------------

g77 should complain when a list of dummy arguments containing an adjustable dummy array does not also contain every variable listed in the dimension list of the adjustable array.

Currently, g77 does complain about a variable that dimensions an array but doesn't appear in any dummy list or COMMON area, but this needs to be extended to catch cases where it doesn't appear in every dummy list that also lists any arrays it dimensions.

For example, g77 should warn about the entry point ALT below, since it includes ARRAY but not ISIZE in its list of arguments:

     SUBROUTINE PRIMARY(ARRAY, ISIZE)
     REAL ARRAY(ISIZE)
     ENTRY ALT(ARRAY)

Invalid FORMAT Specifiers
-------------------------

g77 should check FORMAT specifiers for validity as it does FORMAT statements.

For example, a diagnostic would be produced for:

     PRINT 'HI THERE!'  !User meant PRINT *, 'HI THERE!'

Ambiguous Dialects
------------------

g77 needs a set of options such as -Wugly*, -Wautomatic, -Wvxt, -Wf90, and so on. These would warn about places in the user's source where ambiguities are found, helpful in resolving ambiguities in the program's dialect or dialects.

Unused Labels
-------------

g77 should warn about unused labels when -Wunused is in effect.

Informational Messages
----------------------

g77 needs an option to suppress information messages (notes). -w does this but also suppresses warnings. The default should be to suppress info messages.

Perhaps info messages should simply be eliminated.

Uninitialized Variables at Run Time
-----------------------------------

g77 needs an option to initialize everything (not otherwise explicitly initialized) to ``weird'' (machine-dependent) values, e.g. NaNs, bad (non-NULL) pointers, and largest-magnitude integers, would help track down references to some kinds of uninitialized variables at run time.

Note that use of the options -O -Wuninitialized can catch many such bugs at compile time.

Portable Unformatted Files
--------------------------

g77 has no facility for exchanging unformatted files with systems using different number formats---even differing only in endianness (byte order)---or written by other compilers.  Some compilers provide facilities at least for doing byte-swapping during unformatted I/O.

It is unrealistic to expect to cope with exchanging unformatted files with arbitrary other compiler runtimes, but the g77 runtime should at least be able to read files written by g77 on systems with different number formats, particularly if they differ only in byte order.

In case you do need to write a program to translate to or from g77 (libf2c) unformatted files, they are written as follows:

Sequential
     Unformatted sequential records consist of

      1. A number giving the length of the record contents;

      2. the length of record contents again (for backspace).

     The record length is of C type long; this means that it is 8 bytes on 64-bit systems such as Alpha GNU/Linux and 4 bytes on other systems, such as x86 GNU/Linux. Consequently such files cannot be exchanged between 64-bit and 32-bit systems, even with the same basic number format.

Direct access
     Unformatted direct access files form a byte stream of length RECORDS*RECL bytes, where RECORDS is the maximum record number (REC=RECORDS) written and RECL is the record length in bytes specified in the OPEN statement (RECL=RECL).  Data appear in the records as determined by the relevant WRITE statement.  Dummy records with arbitrary contents appear in the file in place of records which haven't been written.

Thus for exchanging a sequential or direct access unformatted file between big- and little-endian 32-bit systems using IEEE 754 floating point it would be sufficient to reverse the bytes in consecutive words in the file if, and only if, only REAL*4, COMPLEX, INTEGER*4 and/or LOGICAL*4 data have been written to it by g77.

If necessary, it is possible to do byte-oriented i/o with g77's FGETC and FPUTC intrinsics.  Byte-swapping can be done in Fortran by equivalencing larger sized variables to an INTEGER*1 array or a set of scalars.

If you need to exchange binary data between arbitrary system and compiler variations, we recommend using a portable binary format with Fortran bindings, such as NCSA's HDF (http://hdf.ncsa.uiuc.edu/) or PACT's PDB (No, not that one.) (http://www.llnl.gov/def_sci/pact/pact_homepage.html).  (Unlike, say, CDF or XDR, HDF-like systems write in the native number formats and only incur overhead when they are read on a system with a different format.)  A future g77 runtime library should use such techniques.

Better List-directed I/O
------------------------

Values output using list-directed I/O (PRINT *, R, D) should be written with a field width, precision, and so on appropriate for the type (precision) of each value.

(Currently, no distinction is made between single-precision and double-precision values by libf2c.)

It is likely this item will require the libg77 project to be undertaken.

In the meantime, use of formatted I/O is recommended. While it might be of little consolation, g77 does support FORMAT(F<WIDTH>.4), for example, as long as WIDTH is defined as a named constant (via PARAMETER). That at least allows some compile-time specification of the precision of a data type, perhaps controlled by preprocessing directives.

Default to Console I/O
----------------------

The default I/O units, specified by READ FMT, READ (UNIT=*), WRITE (UNIT=*), and PRINT FMT, should not be units 5 (input) and 6 (output), but, rather, unit numbers not normally available for use in statements such as OPEN and CLOSE.

Changing this would allow a program to connect units 5 and 6 to files via OPEN, but still use READ (UNIT=*) and PRINT to do I/O to the ``console''.

This change probably requires the libg77 project.

Labels Visible to Debugger
--------------------------

g77 should output debugging information for statements labels, for use by debuggers that know how to support them. Same with weirder things like construct names. It is not yet known if any debug formats or debuggers support these.

Disappointments and Misunderstandings
=====================================

These problems are perhaps regrettable, but we don't know any practical way around them for now.

Mangling of Names in Source Code
--------------------------------

The current external-interface design, which includes naming of external procedures, COMMON blocks, and the library interface, has various usability problems, including things like adding underscores where not really necessary (and preventing easier inter-language operability) and yet not providing complete namespace freedom for user C code linked with Fortran apps (due to the naming of functions in the library, among other things).

Project GNU should at least get all this ``right'' for systems it fully controls, such as the Hurd, and provide defaults and options for compatibility with existing systems and interoperability with popular existing compilers.

Multiple Definitions of External Names
--------------------------------------

g77 doesn't allow a common block and an external procedure or BLOCK DATA to have the same name. Some systems allow this, but g77 does not, to be compatible with f2c.

g77 could special-case the way it handles BLOCK DATA, since it is not compatible with f2c in this particular area (necessarily, since g77 offers an important feature here), but it is likely that such special-casing would be very annoying to people with programs that use EXTERNAL FOO, with no other mention of FOO in the same program unit, to refer to external procedures, since the result would be that g77 would treat these references as requests to force-load BLOCK DATA program units.

In that case, if g77 modified names of BLOCK DATA so they could have the same names as COMMON, users would find that their programs wouldn't link because the FOO procedure didn't have its name translated the same way.

(Strictly speaking, g77 could emit a null-but-externally-satisfying definition of FOO with its name transformed as if it had been a BLOCK DATA, but that probably invites more trouble than it's worth.)

Limitation on Implicit Declarations
-----------------------------------

g77 disallows IMPLICIT CHARACTER*(*). This is not standard-conforming.

Certain Changes We Don't Want to Make
=====================================

This section lists changes that people frequently request, but which we do not make because we think GNU Fortran is better without them.

Backslash in Constants
----------------------

In the opinion of many experienced Fortran users, -fno-backslash should be the default, not -fbackslash, as currently set by g77.

First of all, you can always specify -fno-backslash to turn off this processing.

Despite not being within the spirit (though apparently within the letter) of the ANSI FORTRAN 77 standard, g77 defaults to -fbackslash because that is what most UNIX f77 commands default to, and apparently lots of code depends on this feature.

This is a particularly troubling issue. The use of a C construct in the midst of Fortran code is bad enough, worse when it makes existing Fortran programs stop working (as happens when programs written for non-UNIX systems are ported to UNIX systems with compilers that provide the -fbackslash feature as the default---sometimes with no option to turn it off).

The author of GNU Fortran wished, for reasons of linguistic purity, to make -fno-backslash the default for GNU Fortran and thus require users of UNIX f77 and f2c to specify -fbackslash to get the UNIX behavior.

However, the realization that g77 is intended as a replacement for UNIX f77, caused the author to choose to make g77 as compatible with f77 as feasible, which meant making -fbackslash the default.

The primary focus on compatibility is at the source-code level, and the question became ``What will users expect a replacement for f77 to do, by default?'' Although at least one UNIX f77 does not provide -fbackslash as a default, it appears that the majority of them do, which suggests that the majority of code that is compiled by UNIX f77 compilers expects -fbackslash to be the default.

It is probably the case that more code exists that would not work with -fbackslash in force than code that requires it be in force.

However, most of that code is not being compiled with f77, and when it is, new build procedures (shell scripts, makefiles, and so on) must be set up anyway so that they work under UNIX. That makes a much more natural and safe opportunity for non-UNIX users to adapt their build procedures for g77's default of -fbackslash than would exist for the majority of UNIX f77 users who would have to modify existing, working build procedures to explicitly specify -fbackslash if that was not the default.

One suggestion has been to configure the default for -fbackslash (and perhaps other options as well) based on the configuration of g77.

This is technically quite straightforward, but will be avoided even in cases where not configuring defaults to be dependent on a particular configuration greatly inconveniences some users of legacy code.

Many users appreciate the GNU compilers because they provide an environment that is uniform across machines. These users would be inconvenienced if the compiler treated things like the format of the source code differently on certain machines.

Occasionally users write programs intended only for a particular machine type. On these occasions, the users would benefit if the GNU Fortran compiler were to support by default the same dialect as the other compilers on that machine. But such applications are rare. And users writing a program to run on more than one type of machine cannot possibly benefit from this kind of compatibility. (This is consistent with the design goals for gcc. To change them for g77, you must first change them for gcc. Do not ask the maintainers of g77 to do this for you, or to disassociate g77 from the widely understood, if not widely agreed-upon, goals for GNU compilers in general.)

This is why GNU Fortran does and will treat backslashes in the same fashion on all types of machines (by default). See Direction of Language Development, for more information on this overall philosophy guiding the development of the GNU Fortran language.

Of course, users strongly concerned about portability should indicate explicitly in their build procedures which options are expected by their source code, or write source code that has as few such expectations as possible.

For example, avoid writing code that depends on backslash (\) being interpreted either way in particular, such as by starting a program unit with:

     CHARACTER BACKSL
     PARAMETER (BACKSL = '\\')

Then, use concatenation of BACKSL anyplace a backslash is desired. In this way, users can write programs which have the same meaning in many Fortran dialects.

(However, this technique does not work for Hollerith constants---which is just as well, since the only generally portable uses for Hollerith constants are in places where character constants can and should be used instead, for readability.)

Initializing Before Specifying
------------------------------

g77 does not allow DATA VAR/1/ to appear in the source code before COMMON VAR, DIMENSION VAR(10), INTEGER VAR, and so on. In general, g77 requires initialization of a variable or array to be specified after all other specifications of attributes (type, size, placement, and so on) of that variable or array are specified (though confirmation of data type is permitted).

It is possible g77 will someday allow all of this, even though it is not allowed by the FORTRAN 77 standard.

Then again, maybe it is better to have g77 always require placement of DATA so that it can possibly immediately write constants to the output file, thus saving time and space.

That is, DATA A/1000000*1/ should perhaps always be immediately writable to canonical assembler, unless it's already known to be in a COMMON area following as-yet-uninitialized stuff, and to do this it cannot be followed by COMMON A.

Context-Sensitive Intrinsicness
-------------------------------

g77 treats procedure references to possible intrinsic names as always enabling their intrinsic nature, regardless of whether the form of the reference is valid for that intrinsic.

For example, CALL SQRT is interpreted by g77 as an invalid reference to the SQRT intrinsic function, because the reference is a subroutine invocation.

First, g77 recognizes the statement CALL SQRT as a reference to a procedure named SQRT, not to a variable with that name (as it would for a statement such as V = SQRT).

Next, g77 establishes that, in the program unit being compiled, SQRT is an intrinsic---not a subroutine that happens to have the same name as an intrinsic (as would be the case if, for example, EXTERNAL SQRT was present).

Finally, g77 recognizes that the form of the reference is invalid for that particular intrinsic. That is, it recognizes that it is invalid for an intrinsic function, such as SQRT, to be invoked as a subroutine.

At that point, g77 issues a diagnostic.

Some users claim that it is ``obvious'' that CALL SQRT references an external subroutine of their own, not an intrinsic function.

However, g77 knows about intrinsic subroutines, not just functions, and is able to support both having the same names, for example.

As a result of this, g77 rejects calls to intrinsics that are not subroutines, and function invocations of intrinsics that are not functions, just as it (and most compilers) rejects invocations of intrinsics with the wrong number (or types) of arguments.

So, use the EXTERNAL SQRT statement in a program unit that calls a user-written subroutine named SQRT.

Context-Sensitive Constants
---------------------------

g77 does not use context to determine the types of constants or named constants (PARAMETER), except for (non-standard) typeless constants such as '123'O.

For example, consider the following statement:

     PRINT *, 9.435784839284958 * 2D0

g77 will interpret the (truncated) constant 9.435784839284958 as a REAL(KIND=1), not REAL(KIND=2), constant, because the suffix D0 is not specified.

As a result, the output of the above statement when compiled by g77 will appear to have ``less precision'' than when compiled by other compilers.

In these and other cases, some compilers detect the fact that a single-precision constant is used in a double-precision context and therefore interpret the single-precision constant as if it was explicitly specified as a double-precision constant. (This has the effect of appending decimal, not binary, zeros to the fractional part of the number---producing different computational results.)

The reason this misfeature is dangerous is that a slight, apparently innocuous change to the source code can change the computational results. Consider:

     REAL ALMOST, CLOSE
     DOUBLE PRECISION FIVE
     PARAMETER (ALMOST = 5.000000000001)
     FIVE = 5
     CLOSE = 5.000000000001
     PRINT *, 5.000000000001 - FIVE
     PRINT *, ALMOST - FIVE
     PRINT *, CLOSE - FIVE
     END

Running the above program should result in the same value being printed three times. With g77 as the compiler, it does.

However, compiled by many other compilers, running the above program would print two or three distinct values, because in two or three of the statements, the constant 5.000000000001, which on most systems is exactly equal to 5. when interpreted as a single-precision constant, is instead interpreted as a double-precision constant, preserving the represented precision. However, this ``clever'' promotion of type does not extend to variables or, in some compilers, to named constants.

Since programmers often are encouraged to replace manifest constants or permanently-assigned variables with named constants (PARAMETER in Fortran), and might need to replace some constants with variables having the same values for pertinent portions of code, it is important that compilers treat code so modified in the same way so that the results of such programs are the same. g77 helps in this regard by treating constants just the same as variables in terms of determining their types in a context-independent way.

Still, there is a lot of existing Fortran code that has been written to depend on the way other compilers freely interpret constants' types based on context, so anything g77 can do to help flag cases of this in such code could be very helpful.

Equivalence Versus Equality
---------------------------

Use of .EQ. and .NE. on LOGICAL operands is not supported, except via -fugly-logint, which is not recommended except for legacy code (where the behavior expected by the code is assumed).

Legacy code should be changed, as resources permit, to use .EQV. and .NEQV. instead, as these are permitted by the various Fortran standards.

New code should never be written expecting .EQ. or .NE. to work if either of its operands is LOGICAL.

The problem with supporting this ``feature'' is that there is unlikely to be consensus on how it works, as illustrated by the following sample program:

     LOGICAL L,M,N
     DATA L,M,N /3*.FALSE./
     IF (L.AND.M.EQ.N) PRINT *,'L.AND.M.EQ.N'
     END

The issue raised by the above sample program is: what is the precedence of .EQ. (and .NE.) when applied to LOGICAL operands?

Some programmers will argue that it is the same as the precedence for .EQ. when applied to numeric (such as INTEGER) operands. By this interpretation, the subexpression M.EQ.N must be evaluated first in the above program, resulting in a program that, when run, does not execute the PRINT statement.

Other programmers will argue that the precedence is the same as the precedence for .EQV., which is restricted by the standards to LOGICAL operands. By this interpretation, the subexpression L.AND.M must be evaluated first, resulting in a program that does execute the PRINT statement.

Assigning arbitrary semantic interpretations to syntactic expressions that might legitimately have more than one ``obvious'' interpretation is generally unwise.

The creators of the various Fortran standards have done a good job in this case, requiring a distinct set of operators (which have their own distinct precedence) to compare LOGICAL operands. This requirement results in expression syntax with more certain precedence (without requiring substantial context), making it easier for programmers to read existing code. g77 will avoid muddying up elements of the Fortran language that were well-designed in the first place.

(Ask C programmers about the precedence of expressions such as (a) & (b) and (a) - (b)---they cannot even tell you, without knowing more context, whether the & and - operators are infix (binary) or unary!)

Most dangerous of all is the fact that, even assuming consensus on its meaning, an expression like L.AND.M.EQ.N, if it is the result of a typographical error, doesn't look like it has such a typo. Even experienced Fortran programmers would not likely notice that L.AND.M.EQV.N was, in fact, intended.

So, this is a prime example of a circumstance in which a quality compiler diagnoses the code, instead of leaving it up to someone debugging it to know to turn on special compiler options that might diagnose it.

Order of Side Effects
---------------------

g77 does not necessarily produce code that, when run, performs side effects (such as those performed by function invocations) in the same order as in some other compiler---or even in the same order as another version, port, or invocation (using different command-line options) of g77.

It is never safe to depend on the order of evaluation of side effects. For example, an expression like this may very well behave differently from one compiler to another:

     J = IFUNC() - IFUNC()

There is no guarantee that IFUNC will be evaluated in any particular order. Either invocation might happen first. If IFUNC returns 5 the first time it is invoked, and returns 12 the second time, J might end up with the value 7, or it might end up with -7.

Generally, in Fortran, procedures with side-effects intended to be visible to the caller are best designed as subroutines, not functions. Examples of such side-effects include:

  * The generation of random numbers that are intended to influence return values.

  * Performing I/O (other than internal I/O to local variables).

  * Updating information in common blocks.

An example of a side-effect that is not intended to be visible to the caller is a function that maintains a cache of recently calculated results, intended solely to speed repeated invocations of the function with identical arguments. Such a function can be safely used in expressions, because if the compiler optimizes away one or more calls to the function, operation of the program is unaffected (aside from being speeded up).

Warning Messages and Error Messages
===================================

The GNU compiler can produce two kinds of diagnostics: errors and warnings. Each kind has a different purpose:

  Errors report problems that make it impossible to compile your program. GNU Fortran reports errors with the source file name, line number, and column within the line where the problem is apparent.

  Warnings report other unusual conditions in your code that might indicate a problem, although compilation can (and does) proceed. Warning messages also report the source file name, line number, and column information, but include the text warning: to distinguish them from error messages.

Warnings might indicate danger points where you should check to make sure that your program really does what you intend; or the use of obsolete features; or the use of nonstandard features of GNU Fortran. Many warnings are issued only if you ask for them, with one of the -W options (for instance, -Wall requests a variety of useful warnings).

Note: Currently, the text of the line and a pointer to the column is printed in most g77 diagnostics.

See Options to Request or Suppress Warnings, for more detail on these and related command-line options.

Open Questions
**************

Please consider offering useful answers to these questions!

  * LOC() and other intrinsics are probably somewhat misclassified. Is the a need for more precise classification of intrinsics, and if so, what are the appropriate groupings? Is there a need to individually enable/disable/delete/hide intrinsics from the command line?

Reporting Bugs
**************

Your bug reports play an essential role in making GNU Fortran reliable.

When you encounter a problem, the first thing to do is to see if it is already known.  See Trouble.  If it isn't known, then you should report the problem.

See Known Causes of Trouble with GNU Fortran, for information on problems we already know about.

See How To Get Help with GNU Fortran, for information on where to ask for help.

Have You Found a Bug?
=====================

If you are not sure whether you have found a bug, here are some guidelines:

  * If the compiler gets a fatal signal, for any input whatever, that is a compiler bug. Reliable compilers never crash---they just remain obsolete.

  * If the compiler produces invalid assembly code, for any input whatever, that is a compiler bug, unless the compiler reports errors (not just warnings) which would ordinarily prevent the assembler from being run.

  * If the compiler produces valid assembly code that does not correctly execute the input source code, that is a compiler bug.

     However, you must double-check to make sure, because you might have run into an incompatibility between GNU Fortran and traditional Fortran. These incompatibilities might be considered bugs, but they are inescapable consequences of valuable features.

     Or you might have a program whose behavior is undefined, which happened by chance to give the desired results with another Fortran compiler. It is best to check the relevant Fortran standard thoroughly if it is possible that the program indeed does something undefined.

     After you have localized the error to a single source line, it should be easy to check for these things. If your program is correct and well defined, you have found a compiler bug.

     It might help if, in your submission, you identified the specific language in the relevant Fortran standard that specifies the desired behavior, if it isn't likely to be obvious and agreed-upon by all Fortran users.

  * If the compiler produces an error message for valid input, that is a compiler bug.

  * If the compiler does not produce an error message for invalid input, that is a compiler bug. However, you should note that your idea of ``invalid input'' might be someone else's idea of ``an extension'' or ``support for traditional practice''.

  * If you are an experienced user of Fortran compilers, your suggestions for improvement of GNU Fortran are welcome in any case.

Many, perhaps most, bug reports against g77 turn out to be bugs in the user's code. While we find such bug reports educational, they sometimes take a considerable amount of time to track down or at least respond to---time we could be spending making g77, not some user's code, better.

Some steps you can take to verify that the bug is not certainly in the code you're compiling with g77:

  * Compile your code using the g77 options -W -Wall -O. These options enable many useful warning; the -O option enables flow analysis that enables the uninitialized-variable warning.

     If you investigate the warnings and find evidence of possible bugs in your code, fix them first and retry g77.

  * Compile your code using the g77 options -finit-local-zero, -fno-automatic, -ffloat-store, and various combinations thereof.

     If your code works with any of these combinations, that is not proof that the bug isn't in g77---a g77 bug exposed by your code might simply be avoided, or have a different, more subtle effect, when different options are used---but it can be a strong indicator that your code is making unwarranted assumptions about the Fortran dialect and/or underlying machine it is being compiled and run on.

     See Overly Convenient Command-Line Options, for information on the -fno-automatic and -finit-local-zero options and how to convert their use into selective changes in your own code.

  * Validate your code with ftnchek or a similar code-checking tool. ftnchek can be found at ftp://ftp.netlib.org/fortran or ftp://ftp.dsm.fordham.edu.

     Here are some sample Makefile rules using ftnchek ``project'' files to do cross-file checking and sfmakedepend (from ftp://ahab.rutgers.edu/pub/perl/sfmakedepend) to maintain dependencies automatically. These assume the use of GNU make.

          # Dummy suffix for ftnchek targets:
          .SUFFIXES: .chek
          .PHONY: chekall

          # How to compile .f files (for implicit rule):
          FC = g77
          # Assume `include' directory:
          FFLAGS = -Iinclude -g -O -Wall

          # Flags for ftnchek:
          CHEK1 = -array=0 -include=includes -noarray
          CHEK2 = -nonovice -usage=1 -notruncation
          CHEKFLAGS = $(CHEK1) $(CHEK2)

          # Run ftnchek with all the .prj files except the one corresponding
          # to the target's root:
          %.chek : %.f ; \
            ftnchek $(filter-out $*.prj,$(PRJS)) $(CHEKFLAGS) \
              -noextern -library $<

          # Derive a project file from a source file:
          %.prj : %.f ; \
            ftnchek $(CHEKFLAGS) -noextern -project -library $<

          # The list of objects is assumed to be in variable OBJS.
          # Sources corresponding to the objects:
          SRCS = $(OBJS:%.o=%.f)
          # ftnchek project files:
          PRJS = $(OBJS:%.o=%.prj)

          # Build the program
          prog: $(OBJS) ; \
            $(FC) -o $ $(OBJS)

          chekall: $(PRJS) ; \
            ftnchek $(CHEKFLAGS) $(PRJS)

          prjs: $(PRJS)

          # For Emacs M-x find-tag:
          TAGS: $(SRCS) ; \
            etags $(SRCS)

          # Rebuild dependencies:
          depend: ; \
            sfmakedepend -I $(PLTLIBDIR) -I includes -a prj $(SRCS1)

  * Try your code out using other Fortran compilers, such as f2c. If it does not work on at least one other compiler (assuming the compiler supports the features the code needs), that is a strong indicator of a bug in the code.

     However, even if your code works on many compilers except g77, that does not mean the bug is in g77. It might mean the bug is in your code, and that g77 simply exposes it more readily than other compilers.

How to Report Bugs
==================

Bugs should be reported to our bug database.  Please refer to http://gcc.gnu.org/bugs.html for up-to-date instructions how to submit bug reports.  Copies of this file in HTML (bugs.html) and plain text (BUGS) are also part of GCC releases.

How To Get Help with GNU Fortran
********************************

If you need help installing, using or changing GNU Fortran, there are two ways to find it:

  * Look in the service directory for someone who might help you for a fee. The service directory is found in the file named SERVICE in the GCC distribution.

  * Send a message to email-help.

Adding Options
**************

To add a new command-line option to g77, first decide what kind of option you wish to add. Search the g77 and gcc documentation for one or more options that is most closely like the one you want to add (in terms of what kind of effect it has, and so on) to help clarify its nature.

  * Fortran options are options that apply only when compiling Fortran programs. They are accepted by g77 and gcc, but they apply only when compiling Fortran programs.

  * Compiler options are options that apply when compiling most any kind of program.

Fortran options are listed in the file path-g77/lang-options.h, which is used during the build of gcc to build a list of all options that are accepted by at least one language's compiler. This list goes into the documented_lang_options array in gcc/toplev.c, which uses this array to determine whether a particular option should be offered to the linked-in front end for processing by calling lang_option_decode, which, for g77, is in path-g77/com.c and just calls ffe_decode_option.

If the linked-in front end ``rejects'' a particular option passed to it, toplev.c just ignores the option, because some language's compiler is willing to accept it.

This allows commands like gcc -fno-asm foo.c bar.f to work, even though Fortran compilation does not currently support the -fno-asm option; even though the f771 version of lang_decode_option rejects -fno-asm, toplev.c doesn't produce a diagnostic because some other language (C) does accept it.

This also means that commands like g77 -fno-asm foo.f yield no diagnostics, despite the fact that no phase of the command was able to recognize and process -fno-asm---perhaps a warning about this would be helpful if it were possible.

Code that processes Fortran options is found in path-g77/top.c, function ffe_decode_option. This code needs to check positive and negative forms of each option.

The defaults for Fortran options are set in their global definitions, also found in path-g77/top.c. Many of these defaults are actually macros defined in path-g77/target.h, since they might be machine-specific. However, since, in practice, GNU compilers should behave the same way on all configurations (especially when it comes to language constructs), the practice of setting defaults in target.h is likely to be deprecated and, ultimately, stopped in future versions of g77.

Accessor macros for Fortran options, used by code in the g77 FFE, are defined in path-g77/top.h.

Compiler options are listed in gcc/toplev.c in the array f_options. An option not listed in lang_options is looked up in f_options and handled from there.

The defaults for compiler options are set in the global definitions for the corresponding variables, some of which are in gcc/toplev.c.

You can set different defaults for Fortran-oriented or Fortran-reticent compiler options by changing the source code of g77 and rebuilding. How to do this depends on the version of g77:

G77 0.5.24 (EGCS 1.1)
G77 0.5.25 (EGCS 1.2 - which became GCC 2.95)
     Change the lang_init_options routine in gcc/gcc/f/com.c.

     (Note that these versions of g77 perform internal consistency checking automatically when the -fversion option is specified.)

G77 0.5.23
G77 0.5.24 (EGCS 1.0)
     Change the way f771 handles the -fset-g77-defaults option, which is always provided as the first option when called by g77 or gcc.

     This code is in ffe_decode_options in path-g77/top.c. Have it change just the variables that you want to default to a different setting for Fortran compiles compared to compiles of other languages.

     The -fset-g77-defaults option is passed to f771 automatically because of the specification information kept in path-g77/lang-specs.h. This file tells the gcc command how to recognize, in this case, Fortran source files (those to be preprocessed, and those that are not), and further, how to invoke the appropriate programs (including f771) to process those source files.

     It is in path-g77/lang-specs.h that -fset-g77-defaults, -fversion, and other options are passed, as appropriate, even when the user has not explicitly specified them. Other ``internal'' options such as -quiet also are passed via this mechanism.

Projects
********

If you want to contribute to g77 by doing research, design, specification, documentation, coding, or testing, the following information should give you some ideas.

Improve Efficiency
==================

Don't bother doing any performance analysis until most of the following items are taken care of, because there's no question they represent serious space/time problems, although some of them show up only given certain kinds of (popular) input.

  * Improve malloc package and its uses to specify more info about memory pools and, where feasible, use obstacks to implement them.

  * Skip over uninitialized portions of aggregate areas (arrays, COMMON areas, EQUIVALENCE areas) so zeros need not be output. This would reduce memory usage for large initialized aggregate areas, even ones with only one initialized element.

     As of version 0.5.18, a portion of this item has already been accomplished.

  * Prescan the statement (in sta.c) so that the nature of the statement is determined as much as possible by looking entirely at its form, and not looking at any context (previous statements, including types of symbols). This would allow ripping out of the statement-confirmation, symbol retraction/confirmation, and diagnostic inhibition mechanisms. Plus, it would result in much-improved diagnostics. For example, CALL some-intrinsic(...), where the intrinsic is not a subroutine intrinsic, would result actual error instead of the unimplemented-statement catch-all.

  * Throughout g77, don't pass line/column pairs where a simple ffewhere type, which points to the error as much as is desired by the configuration, will do, and don't pass ffelexToken types where a simple ffewhere type will do. Then, allow new default configuration of ffewhere such that the source line text is not preserved, and leave it to things like Emacs' next-error function to point to them (now that next-error supports column, or, perhaps, character-offset, numbers). The change in calling sequences should improve performance somewhat, as should not having to save source lines. (Whether this whole item will improve performance is questionable, but it should improve maintainability.)

  * Handle DATA (A(I),I=1,1000000)/1000000*2/ more efficiently, especially as regards the assembly output. Some of this might require improving the back end, but lots of improvement in space/time required in g77 itself can be fairly easily obtained without touching the back end. Maybe type-conversion, where necessary, can be speeded up as well in cases like the one shown (converting the 2 into 2.).

  * If analysis shows it to be worthwhile, optimize lex.c.

  * Consider redesigning lex.c to not need any feedback during tokenization, by keeping track of enough parse state on its own.

Better Optimization
===================

Much of this work should be put off until after g77 has all the features necessary for its widespread acceptance as a useful F77 compiler. However, perhaps this work can be done in parallel during the feature-adding work.

  * Do the equivalent of the trick of putting extern inline in front of every function definition in libg2c and #include'ing the resulting file in f2c+gcc---that is, inline all run-time-library functions that are at all worth inlining. (Some of this has already been done, such as for integral exponentiation.)

  * When doing CHAR_VAR = CHAR_FUNC(...), and it's clear that types line up and CHAR_VAR is addressable or not a VAR_DECL, make CHAR_VAR, not a temporary, be the receiver for CHAR_FUNC. (This is now done for COMPLEX variables.)

  * Design and implement Fortran-specific optimizations that don't really belong in the back end, or where the front end needs to give the back end more info than it currently does.

  * Design and implement a new run-time library interface, with the code going into libgcc so no special linking is required to link Fortran programs using standard language features. This library would speed up lots of things, from I/O (using precompiled formats, doing just one, or, at most, very few, calls for arrays or array sections, and so on) to general computing (array/section implementations of various intrinsics, implementation of commonly performed loops that aren't likely to be optimally compiled otherwise, etc.).

     Among the important things the library would do are:

       * Be a one-stop-shop-type library, hence shareable and usable by all, in that what are now library-build-time options in libg2c would be moved at least to the g77 compile phase, if not to finer grains (such as choosing how list-directed I/O formatting is done by default at OPEN time, for preconnected units via options or even statements in the main program unit, maybe even on a per-I/O basis with appropriate pragma-like devices).

  * Probably requiring the new library design, change interface to normally have COMPLEX functions return their values in the way gcc would if they were declared __complex__ float, rather than using the mechanism currently used by CHARACTER functions (whereby the functions are compiled as returning void and their first arg is a pointer to where to store the result). (Don't append underscores to external names for COMPLEX functions in some cases once g77 uses gcc rather than f2c calling conventions.)

  * Do something useful with doiter references where possible. For example, CALL FOO(I) cannot modify I if within a DO loop that uses I as the iteration variable, and the back end might find that info useful in determining whether it needs to read I back into a register after the call. (It normally has to do that, unless it knows FOO never modifies its passed-by-reference argument, which is rarely the case for Fortran-77 code.)

Simplify Porting
================

Making g77 easier to configure, port, build, and install, either as a single-system compiler or as a cross-compiler, would be very useful.

  * A new library (replacing libg2c) should improve portability as well as produce more optimal code. Further, g77 and the new library should conspire to simplify naming of externals, such as by removing unnecessarily added underscores, and to reduce/eliminate the possibility of naming conflicts, while making debugger more straightforward.

     Also, it should make multi-language applications more feasible, such as by providing Fortran intrinsics that get Fortran unit numbers given C FILE * descriptors.

  * Possibly related to a new library, g77 should produce the equivalent of a gcc main(argc, argv) function when it compiles a main program unit, instead of compiling something that must be called by a library implementation of main().

     This would do many useful things such as provide more flexibility in terms of setting up exception handling, not requiring programmers to start their debugging sessions with breakpoint MAIN__ followed by run, and so on.

  * The GBE needs to understand the difference between alignment requirements and desires. For example, on Intel x86 machines, g77 currently imposes overly strict alignment requirements, due to the back end, but it would be useful for Fortran and C programmers to be able to override these recommendations as long as they don't violate the actual processor requirements.

More Extensions
===============

These extensions are not the sort of things users ask for ``by name'', but they might improve the usability of g77, and Fortran in general, in the long run. Some of these items really pertain to improving g77 internals so that some popular extensions can be more easily supported.

  * Look through all the documentation on the GNU Fortran language, dialects, compiler, missing features, bugs, and so on. Many mentions of incomplete or missing features are sprinkled throughout. It is not worth repeating them here.

  * Consider adding a NUMERIC type to designate typeless numeric constants, named and unnamed. The idea is to provide a forward-looking, effective replacement for things like the old-style PARAMETER statement when people really need typelessness in a maintainable, portable, clearly documented way. Maybe TYPELESS would include CHARACTER, POINTER, and whatever else might come along. (This is not really a call for polymorphism per se, just an ability to express limited, syntactic polymorphism.)

  * Support OPEN(...,KEY=(...),...).

  * Support arbitrary file unit numbers, instead of limiting them to 0 through MXUNIT-1. (This is a libg2c issue.)

  * OPEN(NOSPANBLOCKS,...) is treated as OPEN(UNIT=NOSPANBLOCKS,...), so a later UNIT= in the first example is invalid. Make sure this is what users of this feature would expect.

  * Currently g77 disallows READ(1'10) since it is an obnoxious syntax, but supporting it might be pretty easy if needed. More details are needed, such as whether general expressions separated by an apostrophe are supported, or maybe the record number can be a general expression, and so on.

  * Support STRUCTURE, UNION, MAP, and RECORD fully. Currently there is no support at all for %FILL in STRUCTURE and related syntax, whereas the rest of the stuff has at least some parsing support. This requires either major changes to libg2c or its replacement.

  * F90 and g77 probably disagree about label scoping relative to INTERFACE and END INTERFACE, and their contained procedure interface bodies (blocks?).

  * ENTRY doesn't support F90 RESULT() yet, since that was added after S8.112.

  * Empty-statement handling (10 ;;CONTINUE;;) probably isn't consistent with the final form of the standard (it was vague at S8.112).

  * It seems to be an ``open'' question whether a file, immediately after being OPENed,is positioned at the beginning, the end, or wherever---it might be nice to offer an option of opening to ``undefined'' status, requiring an explicit absolute-positioning operation to be performed before any other (besides CLOSE) to assist in making applications port to systems (some IBM?) that OPEN to the end of a file or some such thing.

Machine Model
=============

This items pertain to generalizing g77's view of the machine model to more fully accept whatever the GBE provides it via its configuration.

  * Switch to using REAL_VALUE_TYPE to represent floating-point constants exclusively so the target float format need not be required. This means changing the way g77 handles initialization of aggregate areas having more than one type, such as REAL and INTEGER, because currently it initializes them as if they were arrays of char and uses the bit patterns of the constants of the various types in them to determine what to stuff in elements of the arrays.

  * Rely more and more on back-end info and capabilities, especially in the area of constants (where having the g77 front-end's IL just store the appropriate tree nodes containing constants might be best).

  * Suite of C and Fortran programs that a user/administrator can run on a machine to help determine the configuration for g77 before building and help determine if the compiler works (especially with whatever libraries are installed) after building.

Internals Documentation
=======================

Better info on how g77 works and how to port it is needed.

See Front End, which contains some information on g77 internals.

Internals Improvements
======================

Some more items that would make g77 more reliable and easier to maintain:

  * Generally make expression handling focus more on critical syntax stuff, leaving semantics to callers. For example, anything a caller can check, semantically, let it do so, rather than having expr.c do it. (Exceptions might include things like diagnosing FOO(I--K:)=BAR where FOO is a PARAMETER---if it seems important to preserve the left-to-right-in-source order of production of diagnostics.)

  * Come up with better naming conventions for -D to establish requirements to achieve desired implementation dialect via proj.h.

  * Clean up used tokens and ffewheres in ffeglobal_terminate_1.

  * Replace sta.c outpooldisp mechanism with malloc_pool_use.

  * Check for opANY in more places in com.c, std.c, and ste.c, and get rid of the opCONVERT(opANY) kludge (after determining if there is indeed no real need for it).

  * Utility to read and check bad.def messages and their references in the code, to make sure calls are consistent with message templates.

  * Search and fix &ffe... and similar so that ffe...ptr... macros are available instead (a good argument for wishing this could have written all this stuff in C++, perhaps). On the other hand, it's questionable whether this sort of improvement is really necessary, given the availability of tools such as Emacs and Perl, which make finding any address-taking of structure members easy enough?

  * Some modules truly export the member names of their structures (and the structures themselves), maybe fix this, and fix other modules that just appear to as well (by appending _, though it'd be ugly and probably not worth the time).

  * Implement C macros RETURNS(value) and SETS(something,value) in proj.h and use them throughout g77 source code (especially in the definitions of access macros in .h files) so they can be tailored to catch code writing into a RETURNS() or reading from a SETS().

  * Decorate throughout with const and other such stuff.

  * All F90 notational derivations in the source code are still based on the S8.112 version of the draft standard. Probably should update to the official standard, or put documentation of the rules as used in the code...uh...in the code.

  * Some ffebld_new calls (those outside of ffeexpr.c or inside but invoked via paths not involving ffeexpr_lhs or ffeexpr_rhs) might be creating things in improper pools, leading to such things staying around too long or (doubtful, but possible and dangerous) not long enough.

  * Some ffebld_list_new (or whatever) calls might not be matched by ffebld_list_bottom (or whatever) calls, which might someday matter. (It definitely is not a problem just yet.)

  * Probably not doing clean things when we fail to EQUIVALENCE something due to alignment/mismatch or other problems---they end up without ffestorag objects, so maybe the backend (and other parts of the front end) can notice that and handle like an opANY (do what it wants, just don't complain or crash). Most of this seems to have been addressed by now, but a code review wouldn't hurt.

Better Diagnostics
==================

These are things users might not ask about, or that need to be looked into, before worrying about. Also here are items that involve reducing unnecessary diagnostic clutter.

  * When FUNCTION and ENTRY point types disagree (CHARACTER lengths, type classes, and so on), ANY-ize the offending ENTRY point and any new dummies it specifies.

  * Speed up and improve error handling for data when repeat-count is specified. For example, don't output 20 unnecessary messages after the first necessary one for:

          INTEGER X(20)
          CONTINUE
          DATA (X(I), J= 1, 20) /20*5/
          END

     (The CONTINUE statement ensures the DATA statement is processed in the context of executable, not specification, statements.)

     [file ffe.texi not included]

Diagnostics
***********

Some diagnostics produced by g77 require sufficient explanation that the explanations are given below, and the diagnostics themselves identify the appropriate explanation.

Identification uses the GNU Info format---specifically, the info command that displays the explanation is given within square brackets in the diagnostic. For example:

     foo.f:5: Invalid statement [info -f g77 M FOOEY]

More details about the above diagnostic is found in the g77 Info documentation, menu item M, submenu item FOOEY, which is displayed by typing the UNIX command info -f g77 M FOOEY.

Other Info readers, such as EMACS, may be just as easily used to display the pertinent node. In the above example, g77 is the Info document name, M is the top-level menu item to select, and, in that node (named Diagnostics, the name of this chapter, which is the very text you're reading now), FOOEY is the menu item to select.

CMPAMBIG
========

     Ambiguous use of intrinsic INTRINSIC ...

The type of the argument to the invocation of the INTRINSIC intrinsic is a COMPLEX type other than COMPLEX(KIND=1). Typically, it is COMPLEX(KIND=2), also known as DOUBLE COMPLEX.

The interpretation of this invocation depends on the particular dialect of Fortran for which the code was written. Some dialects convert the real part of the argument to REAL(KIND=1), thus losing precision; other dialects, and Fortran 90, do no such conversion.

So, GNU Fortran rejects such invocations except under certain circumstances, to avoid making an incorrect assumption that results in generating the wrong code.

To determine the dialect of the program unit, perhaps even whether that particular invocation is properly coded, determine how the result of the intrinsic is used.

The result of INTRINSIC is expected (by the original programmer) to be REAL(KIND=1) (the non-Fortran-90 interpretation) if:

  * It is passed as an argument to a procedure that explicitly or implicitly declares that argument REAL(KIND=1).

     For example, a procedure with no DOUBLE PRECISION or IMPLICIT DOUBLE PRECISION statement specifying the dummy argument corresponding to an actual argument of REAL(Z), where Z is declared DOUBLE COMPLEX, strongly suggests that the programmer expected REAL(Z) to return REAL(KIND=1) instead of REAL(KIND=2).

  * It is used in a context that would otherwise not include any REAL(KIND=2) but where treating the INTRINSIC invocation as REAL(KIND=2) would result in unnecessary promotions and (typically) more expensive operations on the wider type.

     For example:

          DOUBLE COMPLEX Z
          ...
          R(1) = T * REAL(Z)

     The above example suggests the programmer expected the real part of Z to be converted to REAL(KIND=1) before being multiplied by T (presumed, along with R above, to be type REAL(KIND=1)).

     Otherwise, the conversion would have to be delayed until after the multiplication, requiring not only an extra conversion (of T to REAL(KIND=2)), but a (typically) more expensive multiplication (a double-precision multiplication instead of a single-precision one).

The result of INTRINSIC is expected (by the original programmer) to be REAL(KIND=2) (the Fortran 90 interpretation) if:

  * It is passed as an argument to a procedure that explicitly or implicitly declares that argument REAL(KIND=2).

     For example, a procedure specifying a DOUBLE PRECISION dummy argument corresponding to an actual argument of REAL(Z), where Z is declared DOUBLE COMPLEX, strongly suggests that the programmer expected REAL(Z) to return REAL(KIND=2) instead of REAL(KIND=1).

  * It is used in an expression context that includes other REAL(KIND=2) operands, or is assigned to a REAL(KIND=2) variable or array element.

     For example:

          DOUBLE COMPLEX Z
          DOUBLE PRECISION R, T
          ...
          R(1) = T * REAL(Z)

     The above example suggests the programmer expected the real part of Z to not be converted to REAL(KIND=1) by the REAL() intrinsic.

     Otherwise, the conversion would have to be immediately followed by a conversion back to REAL(KIND=2), losing the original, full precision of the real part of Z, before being multiplied by T.

Once you have determined whether a particular invocation of INTRINSIC expects the Fortran 90 interpretation, you can:

  * Change it to DBLE(EXPR) (if INTRINSIC is REAL) or DIMAG(EXPR) (if INTRINSIC is AIMAG) if it expected the Fortran 90 interpretation.

     This assumes EXPR is COMPLEX(KIND=2)---if it is some other type, such as COMPLEX*32, you should use the appropriate intrinsic, such as the one to convert to REAL*16 (perhaps DBLEQ() in place of DBLE(), and QIMAG() in place of DIMAG()).

  * Change it to REAL(INTRINSIC(EXPR)), otherwise. This converts to REAL(KIND=1) in all working Fortran compilers.

If you don't want to change the code, and you are certain that all ambiguous invocations of INTRINSIC in the source file have the same expectation regarding interpretation, you can:

  * Compile with the g77 option -ff90, to enable the Fortran 90 interpretation.

  * Compile with the g77 options -fno-f90 -fugly-complex, to enable the non-Fortran-90 interpretations.

See REAL() and AIMAG() of Complex, for more information on this issue.

Note: If the above suggestions don't produce enough evidence as to whether a particular program expects the Fortran 90 interpretation of this ambiguous invocation of INTRINSIC, there is one more thing you can try.

If you have access to most or all the compilers used on the program to create successfully tested and deployed executables, read the documentation for, and also test out, each compiler to determine how it treats the INTRINSIC intrinsic in this case. (If all the compilers don't agree on an interpretation, there might be lurking bugs in the deployed versions of the program.)

The following sample program might help:

           PROGRAM JCB003
     C
     C Written by James Craig Burley 1997-02-23.
     C
     C Determine how compilers handle non-standard REAL
     C and AIMAG on DOUBLE COMPLEX operands.
     C
           DOUBLE COMPLEX Z
           REAL R
           Z = (3.3D0, 4.4D0)
           R = Z
           CALL DUMDUM(Z, R)
           R = REAL(Z) - R
           IF (R .NE. 0.) PRINT *, 'REAL() is Fortran 90'
           IF (R .EQ. 0.) PRINT *, 'REAL() is not Fortran 90'
           R = 4.4D0
           CALL DUMDUM(Z, R)
           R = AIMAG(Z) - R
           IF (R .NE. 0.) PRINT *, 'AIMAG() is Fortran 90'
           IF (R .EQ. 0.) PRINT *, 'AIMAG() is not Fortran 90'
           END
     C
     C Just to make sure compiler doesn't use naive flow
     C analysis to optimize away careful work above,
     C which might invalidate results....
     C
           SUBROUTINE DUMDUM(Z, R)
           DOUBLE COMPLEX Z
           REAL R
           END

If the above program prints contradictory results on a particular compiler, run away!

EXPIMP
======

     Intrinsic INTRINSIC referenced ...

The INTRINSIC is explicitly declared in one program unit in the source file and implicitly used as an intrinsic in another program unit in the same source file.

This diagnostic is designed to catch cases where a program might depend on using the name INTRINSIC as an intrinsic in one program unit and as a global name (such as the name of a subroutine or function) in another, but g77 recognizes the name as an intrinsic in both cases.

After verifying that the program unit making implicit use of the intrinsic is indeed written expecting the intrinsic, add an INTRINSIC INTRINSIC statement to that program unit to prevent this warning.

This and related warnings are disabled by using the -Wno-globals option when compiling.

Note that this warning is not issued for standard intrinsics. Standard intrinsics include those described in the FORTRAN 77 standard and, if -ff90 is specified, those described in the Fortran 90 standard. Such intrinsics are not as likely to be confused with user procedures as intrinsics provided as extensions to the standard by g77.

INTGLOB
=======

     Same name `INTRINSIC' given ...

The name INTRINSIC is used for a global entity (a common block or a program unit) in one program unit and implicitly used as an intrinsic in another program unit.

This diagnostic is designed to catch cases where a program intends to use a name entirely as a global name, but g77 recognizes the name as an intrinsic in the program unit that references the name, a situation that would likely produce incorrect code.

For example:

     INTEGER FUNCTION TIME()
     ...
     END
     ...
     PROGRAM SAMP
     INTEGER TIME
     PRINT *, 'Time is ', TIME()
     END

The above example defines a program unit named TIME, but the reference to TIME in the main program unit SAMP is normally treated by g77 as a reference to the intrinsic TIME() (unless a command-line option that prevents such treatment has been specified).

As a result, the program SAMP will not invoke the TIME function in the same source file.

Since g77 recognizes libU77 procedures as intrinsics, and since some existing code uses the same names for its own procedures as used by some libU77 procedures, this situation is expected to arise often enough to make this sort of warning worth issuing.

After verifying that the program unit making implicit use of the intrinsic is indeed written expecting the intrinsic, add an INTRINSIC INTRINSIC statement to that program unit to prevent this warning.

Or, if you believe the program unit is designed to invoke the program-defined procedure instead of the intrinsic (as recognized by g77), add an EXTERNAL INTRINSIC statement to the program unit that references the name to prevent this warning.

This and related warnings are disabled by using the -Wno-globals option when compiling.

Note that this warning is not issued for standard intrinsics. Standard intrinsics include those described in the FORTRAN 77 standard and, if -ff90 is specified, those described in the Fortran 90 standard. Such intrinsics are not as likely to be confused with user procedures as intrinsics provided as extensions to the standard by g77.

LEX
===

     Unrecognized character ...
     Invalid first character ...
     Line too long ...
     Non-numeric character ...
     Continuation indicator ...
     Label at ... invalid with continuation line indicator ...
     Character constant ...
     Continuation line ...
     Statement at ... begins with invalid token

Although the diagnostics identify specific problems, they can be produced when general problems such as the following occur:

  * The source file contains something other than Fortran code.

     If the code in the file does not look like many of the examples elsewhere in this document, it might not be Fortran code. (Note that Fortran code often is written in lower case letters, while the examples in this document use upper case letters, for stylistic reasons.)

     For example, if the file contains lots of strange-looking characters, it might be APL source code; if it contains lots of parentheses, it might be Lisp source code; if it contains lots of bugs, it might be C++ source code.

  * The source file contains free-form Fortran code, but -ffree-form was not specified on the command line to compile it.

     Free form is a newer form for Fortran code. The older, classic form is called fixed form.

     Fixed-form code is visually fairly distinctive, because numerical labels and comments are all that appear in the first five columns of a line, the sixth column is reserved to denote continuation lines, and actual statements start at or beyond column 7. Spaces generally are not significant, so if you see statements such as REALX,Y and DO10I=1,100, you are looking at fixed-form code. Comment lines are indicated by the letter C or the symbol * in column 1. (Some code uses ! or /* to begin in-line comments, which many compilers support.)

     Free-form code is distinguished from fixed-form source primarily by the fact that statements may start anywhere. (If lots of statements start in columns 1 through 6, that's a strong indicator of free-form source.) Consecutive keywords must be separated by spaces, so REALX,Y is not valid, while REAL X,Y is. There are no comment lines per se, but ! starts a comment anywhere in a line (other than within a character or Hollerith constant).

     See Source Form, for more information.

  * The source file is in fixed form and has been edited without sensitivity to the column requirements.

     Statements in fixed-form code must be entirely contained within columns 7 through 72 on a given line. Starting them ``early'' is more likely to result in diagnostics than finishing them ``late'', though both kinds of errors are often caught at compile time.

     For example, if the following code fragment is edited by following the commented instructions literally, the result, shown afterward, would produce a diagnostic when compiled:

          C On XYZZY systems, remove "C" on next line:
          C     CALL XYZZY_RESET

     The result of editing the above line might be:

          C On XYZZY systems, remove "C" on next line:
               CALL XYZZY_RESET

     However, that leaves the first C in the CALL statement in column 6, making it a comment line, which is not really what the author intended, and which is likely to result in one of the above-listed diagnostics.

     Replacing the C in column 1 with a space is the proper change to make, to ensure the CALL keyword starts in or after column 7.

     Another common mistake like this is to forget that fixed-form source lines are significant through only column 72, and that, normally, any text beyond column 72 is ignored or is diagnosed at compile time.

     See Source Form, for more information.

  * The source file requires preprocessing, and the preprocessing is not being specified at compile time.

     A source file containing lines beginning with #define, #include, #if, and so on is likely one that requires preprocessing.

     If the file's suffix is .f, .for, or .FOR, the file normally will be compiled without preprocessing by g77.

     Change the file's suffix from .f to .F (or, on systems with case-insensitive file names, to .fpp or .FPP), from .for to .fpp, or from .FOR to .FPP. g77 compiles files with such names with preprocessing.

     Or, learn how to use gcc's -x option to specify the language f77-cpp-input for Fortran files that require preprocessing. See Options Controlling the Kind of Output (Using the GNU Compiler Collection (GCC)).

  * The source file is preprocessed, and the results of preprocessing result in syntactic errors that are not necessarily obvious to someone examining the source file itself.

     Examples of errors resulting from preprocessor macro expansion include exceeding the line-length limit, improperly starting, terminating, or incorporating the apostrophe or double-quote in a character constant, improperly forming a Hollerith constant, and so on.

     See Options Controlling the Kind of Output, for suggestions about how to use, and not use, preprocessing for Fortran code.

GLOBALS
=======

     Global name NAME defined at ... already defined...
     Global name NAME at ... has different type...
     Too many arguments passed to NAME at ...
     Too few arguments passed to NAME at ...
     Argument #N of NAME is ...

These messages all identify disagreements about the global procedure named NAME among different program units (usually including NAME itself).

Whether a particular disagreement is reported as a warning or an error can depend on the relative order of the disagreeing portions of the source file.

Disagreements between a procedure invocation and the subsequent procedure itself are, usually, diagnosed as errors when the procedure itself precedes the invocation. Other disagreements are diagnosed via warnings.

This distinction, between warnings and errors, is due primarily to the present tendency of the gcc back end to inline only those procedure invocations that are preceded by the corresponding procedure definitions. If the gcc back end is changed to inline ``forward references'', in which invocations precede definitions, the g77 front end will be changed to treat both orderings as errors, accordingly.

The sorts of disagreements that are diagnosed by g77 include whether a procedure is a subroutine or function; if it is a function, the type of the return value of the procedure; the number of arguments the procedure accepts; and the type of each argument.

Disagreements regarding global names among program units in a Fortran program should be fixed in the code itself. However, if that is not immediately practical, and the code has been working for some time, it is possible it will work when compiled with the -fno-globals option.

The -fno-globals option causes these diagnostics to all be warnings and disables all inlining of references to global procedures (to avoid subsequent compiler crashes and bad-code generation). Use of the -Wno-globals option as well as -fno-globals suppresses all of these diagnostics. (-Wno-globals by itself disables only the warnings, not the errors.)

After using -fno-globals to work around these problems, it is wise to stop using that option and address them by fixing the Fortran code, because such problems, while they might not actually result in bugs on some systems, indicate that the code is not as portable as it could be. In particular, the code might appear to work on a particular system, but have bugs that affect the reliability of the data without exhibiting any other outward manifestations of the bugs.

LINKFAIL
========

On AIX 4.1, g77 might not build with the native (non-GNU) tools due to a linker bug in coping with the -bbigtoc option which leads to a Relocation overflow error.  The GNU linker is not recommended on current AIX versions, though; it was developed under a now-unsupported version.  This bug is said to be fixed by `update PTF U455193 for APAR IX75823'.

Compiling with -mminimal-toc might solve this problem, e.g. by adding

     BOOT_CFLAGS='-mminimal-toc -O2 -g'

to the make bootstrap command line.

Y2KBAD
======

     Intrinsic `NAME', invoked at (^), known to be non-Y2K-compliant...

This diagnostic indicates that the specific intrinsic invoked by the name NAME is known to have an interface that is not Year-2000 (Y2K) compliant.

See Year 2000 (Y2K) Problems.