This file explains how to use the GNU Fortran system. Copyright (C) 1995 Free Software Foundation, Inc. You may copy, distribute, and modify it freely as long as you preserve this copyright notice and permission notice. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). 1996-03-23 [WARNING: THIS FILE IS BEING DEPRECATED as of version 0.5.18 of GNU Fortran. This is the last version of this file that is up-to-date with respect to changes to GNU Fortran itself. In future versions of GNU Fortran, this file will become obsolete and, at some point, will be removed from the distribution entirely. The contents of this file have been assimilated into the Info documentation for GNU Fortran, newly available as of version 0.5.18. The one-version overlap, or coexistence, of both the Info documentation and the contents of this file, is being provided for your convenience in discovering information on what's new for g77-0.5.18 without having to immediately plunge into the new Info documentation.] Please read all of this information before using (especially before complaining about) g77. Contents: *WHAT IS GNU FORTRAN?* *IMPORTANT GENERAL INFORMATION* *PORTING INFORMATION* *USING THE g77 COMMAND* *SUMMARY OF FORTRAN-SPECIFIC COMMAND-LINE OPTIONS* *SUMMARY OF COMPILATION OPTIONS USEFUL TO FORTRAN USERS* *SUMMARY OF OVERLY CONVENIENT COMMAND-LINE OPTIONS* *USER-VISIBLE CHANGES DURING 0.5.x* *WHAT IS AND ISN'T SUPPORTED* *BLOCK DATA AND LIBRARIES* *FORTRAN 90* *SOURCE CODE FORM* *TYPES, SIZES, PRECISIONS, AND CONSTANTS* *VAX FORTRAN VERSUS FORTRAN 90* *LIBRARY AND PROCEDURE-CALLING INTERFACE* *OPTIONS FOR POTENTIALLY BUGGY PROGRAMS* *OPTIONS FOR SPEEDING UP PROGRAMS* *PEDANTIC COMPILATION* *UGLY FEATURES* *CASE SENSITIVITY IN SOURCE CODE* *INTRINSIC GROUPS* *TROUBLE (BUGS, ETC.)* *ADVANTAGES OVER f2c* *DISAPPOINTMENTS AND MISUNDERSTANDINGS* *OPEN QUESTIONS* *INTERFACING, DEBUGGING, ETC.* *WHAT IS GNU FORTRAN?* GNU Fortran is designed initially as a free replacement for, or alternative to, the Unix `f77' command. It consists of several components: - A modified version of the `gcc' command, which also might be installed as the system's `cc' - The `g77' command, which also might be installed as the system's `f77' - The `libf2c' library - The compiler itself, internally named `f771' The `gcc' command is provided as part of the GNU CC compiler, designed initially as a free replacement for, or alternative to, the Unix `cc' command. `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, then the C compiler (internally named `cc1'), then the assembler (usually `as'), then the linker (usually named `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'). When GNU Fortran is included and built with the GNU CC source tree, the resulting version of `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. Fortran source files are recognized by their file name suffixes: *.f, *.for: Fortran source files (no preprocessing) *.F, *.fpp: Fortran source files (preprocessed via `cpp') UNIX users typically use the *.f and *.F nomenclature. Users of other operating systems, especially those that cannot distinguish upper-case letters from lower-case letters in their file names, typically use the *.for and *.fpp nomenclature. Use of the preprocessor `cpp' allows use of C-like constructs such as "#define" and "#include", but can lead to unexpected, even mistaken, results due to Fortran's source file format. Limiting use of the preprocessor to "#include" and, in conjunction with "#define" only "#if" and related directives, thus avoiding in-line macro expansion entirely, is recommended, especially when using the traditional fixed source form. (With free source form, fewer unexpected transformations are likely to happen, but use of Hollerith and things like continued character constants can nevertheless present problems.) 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 (`libf2c' and `lm'). `g77' can still compile and link programs and source files written in other languages. 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'. 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. Things like trigonometric functions and doing I/O are compiled by the `f771' compiler (invoked by `g77' when compiling Fortran code) into calls to procedures in `libf2c', so `libf2c' must be linked with almost every program with any component compiled by GNU Fortran. (As mentioned above, the `g77' command takes care of all this for you.) The `f771' compiler represents most of what is unique to GNU Fortran. While the `libf2c' component is really part of f2c, a free Fortran-to- C converter distributed by Bellcore (AT&T), 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. 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. 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) have a general similarity 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). *IMPORTANT GENERAL INFORMATION* 1. g77 currently is implemented as a replacement for the f2c+gcc combination, and its implementation is designed so it can, in most cases, generate object files that are link-compatible with those generated by f2c+gcc using the identical combination (which includes a similar/identical copy of f2c.h). Therefore, the g77-gcc C-Fortran interface ought to work in a way that is consistent with f2c. For instance, 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+gcc. However, it is expected that a future version of g77 will not by default generate object files compatible with f2c+gcc and not 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 (which should at the very least trigger compiler warning messages, if not enable f2c compatibility compilation, in future versions of g77). 2. Due to #1 above, object files compiled by g77 are not expected to work well with objects compiled by the native compiler. Libraries compiled with the native compiler will probably have to be recompiled with g77 to be used with g77. There are two reasons for this: (1) there may be subtle type mismatches which cause subroutine arguments and function return values to get corrupted; (2) 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 instance, on the Sun you would have to add "-L/usr/lang/SCx.x -lF77 -lV77" to the link command. 3. 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, i.e. `g77 foo.f -lc'. g77 already specifies `-lf2c -lm' when it calls the linker, but it cannot also specify `-lc' because not all systems have a libc.a. *PORTING INFORMATION* During the private alpha test phase, which lasted about 2.5 years, g77 was tested by a small number of people worldwide on a fairly wide variety of machines. Some improvements have been made in g77 in version 0.5.17 that make it easier for g77 to be configured as a cross-compiler. There is still one known bug (a design bug to be fixed in 0.6) that prevents configuration of g77 as a cross-compiler under some circumstances, though there are assumptions made during configuration that probably make doing non-self-hosting builds a hassle, requiring manual intervention. Generally, g77 can be ported to any configuration to which gcc and f2c+libf2c can be ported, aside from some of the known problems in g77 that are scheduled to be fixed for version 0.6. But, if you are unable to port gcc and f2c (or at least the libF77 and liI77 libraries) to a particular configuration, don't bother asking the g77 maintainer about a g77 port -- the feasability of that project depends largely on a gcc port first being done, so talk to the gcc maintainers about that (e.g. look in the gcc/SERVICE file for information on people who might be willing to do such a port). *USING THE g77 COMMAND* The `g77' command is designed to make compiling and linking Fortran programs somewhat easier than using the `gcc' command. 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. Use `--driver=true' to disable actual invocation of `gcc' (since `true' is the name of a UNIX command that simply returns success status). In addition to supporting all the options supported by the `gcc' command, the `g77' command also supports this option: --driver=COMMAND Specifies that COMMAND, rather than `gcc', is to be invoked by `g77' to do its job. Example: Within the gcc build directory after building GNU Fortran (but without having to install it), `g77 --driver=./xgcc foo.f'. *SUMMARY OF FORTRAN-SPECIFIC COMMAND-LINE OPTIONS* These options are supported both by `g77' and by `gcc' as modified (and reinstalled) by the `g77' distribution. `*' indicates defaults, where appropriate. -fversion Ensure that the g77-specific version of the compiler phase is reported, if run. (This is supplied by default when `-v' or `--version' is specified when invoking `g77' or `gcc' to compile one or more Fortran source files.) -fident * -fno-ident Specify whether to process #ident directives. -ff90 -fno-f90 * Specify whether to allow certain F90 constructs. NOTE: This also changes the interpretation of `REAL(Z)', where Z is type DOUBLE COMPLEX. With -fno-f90 in force, that expression is defined to return type REAL, to conform to apparent industry convention for the DOUBLE COMPLEX extension to FORTRAN 77. With -ff90 in force, that expression is defined to return type DOUBLE PRECISION. In other words, with -fno-f90, REAL(Z) is the same as REAL(REAL(Z)). With -ff90, it is the same as DBLE(Z). -fautomatic * -fno-automatic Specify whether to assume that unSAVEd variables and arrays are intentionally left unSAVEd. -fdollar-ok -fno-dollar-ok * Specify whether `$' is a valid character in a symbol name. -ff2c * -fno-f2c Specify whether compatibility with f2c-compiled code (other than that in libf2c) is desired. -fno-f2c can generate faster code for things like COMPLEX functions. THE SAME OPTION MUST BE USED FOR COMPILING ALL FORTRAN CODE IN A PARTICULAR PROGRAM!! Note that f2c compatibility is a fairly static target to achieve, though not necessarily perfectly so. However, disabling f2c compatibility definitely causes g77 to generate code that might well be incompatible with future versions of g77 when the same option is in force. 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. -ff2c-library * -fno-f2c-library Specify whether use of `libf2c' is desired (it is currently not valid to specify -fno-f2c-library). -ffree-form -fno-free-form * -ffixed-form * -fno-fixed-form Specify whether fixed (traditional) or free (new with Fortran 90) form is used in the source file. -fpedantic -fno-pedantic * Like -pedantic, but applies only to Fortran constructs (while -pedantic applies to C constructs, such as use of `\e' in a character constant within a directive like `#include', and Fortran constructs as well). -fvxt-not-f90 -ff90-not-vxt * Specify whether Fortran 90 or popular `VXT' extensions such as the TYPE statement are to be assumed for ambiguous constructs -- e.g. with -ff90-not-vxt, `PRINT *,"double-quoted string"' is valid, while with -fvxt-not-f90, `PRINT *,"2000' is valid. There is no way to allow both constructs in the general case, since statements like `PRINT *,"2000 !comment?"' would be ambiguous. -fugly -fno-ugly * Specify whether certain `ugly' constructs are to be quietly accepted by the compiler. Implies the appropriate `ugly-args' and `ugly-init' options. For example, with -fno-ugly, CALL FOO(,) means to pass one null argument, whereas with -fugly, it means to pass two null arguments. -fugly-args * -fno-ugly-args Specify whether passing hollerith and typeless constants as actual arguments is supported (e.g. CALL FOO(4HABCD)). -fugly-init * -fno-ugly-init Specify whether using hollerith and typeless constants as initial values (PARAMETER and DATA), and using character constants to initialize numeric types and vice versa, are supported. (For example, "DATA I/'F'/, CHRVAR/65/, J/4HABCD/" is allowed by -fugly-init.) -finit-local-zero -fno-init-local-zero * Specify whether variables and arrays that are local to a program unit (not in COMMON and not passed as an argument) are to be initialized to binary zeros. Since there is a run-time penalty for such initialization of stack-based (non-SAVEd) variables, it might be a good idea to also use -fno-automatic with -finit-local-zero. -fbackslash * -fno-backslash Specify whether `\' is specially interpreted in character and hollerith constants a la C and some Fortran compilers. For example, with -fbackslash in effect, 'A\nB' specifies three characters, with the second one being newline; with -fno-backslash, it specifies four characters, the second and third being backslash and the letter `n', respectively. Note that making -fbackslash the default is a concession to the community of UNIX `f77' users. This feature is an unfortunate carry-over from the C language, as it contradicts the spirit (though not the letter) of the ANSI FORTRAN 77 standard. At the time the feature was added to f77, it was probably difficult to come up with a better way to provide the ability to specify arbitrary characters wherever they might be needed without doing a lot more work on the compiler, however. Also note that g77's implementation of the feature seems to be more general than that offered by some Fortran compilers such as f2c. g77's implementation basically parallels gcc's, while other compilers might not support '\003' as a single character, for example, resulting in differing interpretations of constants such as 'A\003B'. -funderscoring * -fno-underscoring With -funderscoring in effect, g77 appends two underscores to names with underscores and one underscore to external names with no underscores. Use of -fno-underscoring is not recommended unless you are experimenting with issues such as integration of (GNU) Fortran into existing system environments (vis-a-vis existing libraries, tools, etc.). For example, with -funderscoring, and assuming other defaults like -fcase-lower and that j() and max_count() are external functions while my_var is a local variable, a statement like I = J() + MAX_COUNT (MY_VAR) is implemented as something akin to: i = j_() + max_count__(my_var__); With -fno-underscoring, the same statement is implemented as: i = j() + max_count(my_var); Use of -fno-underscoring allows direct specification of user-defined names while debugging and when interfacing g77-compiled code with other languages. (Note that just because the names match does not mean that the interface implemented by g77 for an external name matches the interface implemented by some other language for that same name! Also note that, with -fno-underscoring, the lack of appended underscores introduces the very real possibility that a user-defined external name will conflict with a name in a system library, which could make finding unresolved-reference bugs quite difficult in some cases -- they might occur at program run time, and show up only as buggy behavior.) In future versions of g77, we hope to improve naming and linking issues so that debugging always involves using the names as they appear in the source, even if the names as seen by the linker are mangled to prevent accidental linking between procedures with incompatible interfaces. -fsecond-underscore * -fno-second-underscore Controls whether to append a second underscore to names of entities specified in the Fortran source file. This option has no effect if -funderscoring is in effect. Otherwise, with -fno-second-underscore, an external name such as `MAX_COUNT' is implemented as a reference to the link-time external symbol `max_count_', isntead of `max_count__'. -fintrin-case-initcap -fintrin-case-upper -fintrin-case-lower * -fintrin-case-any Specify expected case for intrinsic names. -fmatch-case-initcap -fmatch-case-upper -fmatch-case-lower * -fmatch-case-any Specify expected case for keywords. -fsource-case-upper -fsource-case-lower * -fsource-case-preserve Specify whether source text other than character and hollerith constants is to be translated to uppercase, to lowercase, or preserved as is. -fsymbol-case-initcap -fsymbol-case-upper -fsymbol-case-lower -fsymbol-case-any * Specify valid cases for user-defined symbol names. -fcase-strict-upper Same as `-fintrin-case-upper -fmatch-case-upper -fsource-case-preserve -fsymbol-case-upper'. (Requires all pertinent source to be in uppercase.) -fcase-strict-lower Same as `-fintrin-case-lower -fmatch-case-lower -fsource-case-preserve -fsymbol-case-lower'. (Requires all pertinent source to be in lowercase.) -fcase-initcap Same as `-fintrin-case-initcap -fmatch-case-initcap -fsource-case-preserve -fsymbol-case-initcap'. (Requires all pertinent source to be in initial capitals, as in `Print *,SqRt(Value)'.) -fcase-upper Same as `-fintrin-case-any -fmatch-case-any -fsource-case-upper -fsymbol-case-any'. (Maps all pertinent source to uppercase.) -fcase-lower Same as `-fintrin-case-any -fmatch-case-any -fsource-case-lower -fsymbol-case-any'. (Maps all pertinent source to lowercase.) -fcase-preserve Same as `-fintrin-case-any -fmatch-case-any -fsource-case-preserve -fsymbol-case-any'. (Preserves all case in user-defined symbols, while allowing any-case matching of intrinsics and keywords. For example, `call Foo(i,I)' would pass two different variables named `i' and `I' to a procedure named `Foo'.) -fdcp-intrinsics-delete -fdcp-intrinsics-hide -fdcp-intrinsics-disable -fdcp-intrinsics-enable * Specify status of DEC's COMPLEX-related intrinsics. -ff2c-intrinsics-delete -ff2c-intrinsics-hide -ff2c-intrinsics-disable -ff2c-intrinsics-enable * Specify status of f2c-specific intrinsics. -ff90-intrinsics-delete * -ff90-intrinsics-hide -ff90-intrinsics-disable -ff90-intrinsics-enable Specify status of F90-specific intrinsics. -fmil-intrinsics-delete -fmil-intrinsics-hide -fmil-intrinsics-disable -fmil-intrinsics-enable * Specify status of MIL-STD-1753-specific intrinsics. -funix-intrinsics-delete -funix-intrinsics-hide -funix-intrinsics-disable -funix-intrinsics-enable * Specify status of UNIX intrinsics. E.g. if your code invokes FLUSH() as a library function and thus worked at 0.5.15 or earlier, or with f2c or other f77 compilers, either add the EXTERNAL FLUSH statement or, perhaps more convenient for you, compile with the -funix-intrinsics-hide or -funix-intrinsics-delete option. Note that ABORT, EXIT, FLUSH, SIGNAL, and SYSTEM are intrinsic subroutines, not functions (since they have side effects), so to get the return values from SIGNAL and SYSTEM, append a final argument specifying an INTEGER variable or array element to receive the returned status. (For example, "CALL SYSTEM('rm foo',ISTAT)".) FLUSH() accepts an optional single INTEGER argument, since many Fortran implementations allow or require a unit number. Currently, since libf2c does not flush a given unit number, this argument is not used -- all units are flushed by libf2c's implementation of FLUSH(). Do not depend on this behavior -- if you want to flush all units, CALL FLUSH with no arguments. EXIT() accepts an optional single INTEGER argument. If omitted, zero is the default (as in CALL EXIT(0)). The default might change on configurations where the "normal return status" is not zero, however. If you want to return a "success" status, it is best to CALL EXIT with no arguments in your code, and let g77 choose the appropriate default. -fvxt-intrinsics-delete * -fvxt-intrinsics-hide -fvxt-intrinsics-disable -fvxt-intrinsics-enable Specify status of VXT intrinsics. -ffixed-line-length-N Set column after which characters are ignored in typical fixed-form lines in the source file. Popular values for N include 72 (the standard and the default), 80 (card image), and 132 (corresponds to `extended-source' options in some popular compilers). N may be `none', meaning that the entire line is meaningful and that continued character constants never have implicit spaces appended to them to fill out the line. -ffixed-line-length-0 means the same thing as -ffixed-line-length-none. -Wsurprising Warn about "suspicious" constructs. These constructs typically mean something different to a standard-conforming Fortran compiler, such as g77, than the programmer who uses them expects, and these differences can result in subtle, compiler-dependent (even machine-dependent) behavioral differences. The constructs warned about include: - Expressions having two arithmetic operators in a row, such as "X*-Y". Such a construct is nonstandard, and can produce unexpected results in more complicated situations such as "X**-Y*Z". g77, and many other compilers, interpret this example differently than programmers, and a few other compilers, in that they interpret it as "X**(-(Y*Z))" instead of "(X**(-Y))*Z". The difference is notable in examples like "2**-2*1.", which g77 and other compilers evaluate to ".25", but a programmer might expect to evaluate to "0.", due to the way the precedence affects the type promotion. (The -fpedantic option also warns about expressions having two arithmetic operators in a row.) - Expressions with a unary minus followed by an operand and then a binary operator other than plus or minus. For example, "-2**2" produces a warning, because the precedence is "-(2**2)", yielding "-4", not "(-2)**2" (yielding "4") as a programmer might expect. - DO loops with REAL or DOUBLE PRECISION DO variables (including implied-DO loops in I/O and DATA statements), since the implementation required by the standard, combined with the vagaries of floating-point arithmetic on most machines, will likely result in terminating conditions not meeting the programmer's expectations (with regard to the terminal value for the loop). *SUMMARY OF COMPILATION OPTIONS USEFUL TO FORTRAN USERS* Using the gcc info documentation as a reference, here are categories of options that g77 and gcc support when compiling and linking Fortran programs: *Overall Options* *Debugging Options* (though support for -g is incomplete) *Optimization Options* *Preprocessor Options* (some do not affect Fortran's INCLUDE statement) *Assembler Option* *Linker Options* *Directory Options* *Target Options* *Machine Dependent Options* (some might not work for Fortran, however) *Code Generation Options* (beware -fno-common, however) g77 supports many other options supported by gcc that apply to code generation and preprocessing, but does not support options that apply to interpreting C or C++ programs. g77 also does not yet support some options such as `-Wid-clash-N', nor does it yet support `-g' fully (as noted above). Here are some options that are more generally applicable to gcc than just the g77 environment, but which might nevertheless be particularly interesting to g77 users. See the explanations for these options in the gcc documentation, in addition to whatever explanations have been cobbled together below. -ffast-math -ffloat-store -fsyntax-only -fmove-all-movables -freduce-all-givs -frerun-loop-opt See the gcc documentation. -pedantic -pedantic-errors These options imply -fpedantic, described in this documentation. See the gcc documentation for more information on their general meaning. -mieee-fp (i386 and similar configurations only) See the gcc documentation. -w -W -Werror -Wimplicit -Wuninitialized -Wunused g77 has code to support these gcc options. See the gcc documentation. Note that for -Wuninitialized to work, optimization must be specified (via `-O', for example). `-Wimplicit' has the effect of using the IMPLICIT NONE statement in every program unit, and as such is g77's version of what f77 traditionally provides via the `-u' option. -Wall Currently the same as `-Wunused' and, if optimization is enabled, `-Wuninitialized' as well. Future versions of g77 might add more warnings that are also enabled via `-Wall', using the same general policy used to make these decisions for gcc. -I- -Idir See gcc documentation for information on the `-I' option. When compiling Fortran source files, `-I' affects not only preprocessor interpretation of #include, but compiler-phase interpretation of the INCLUDE statement as well. Note that `-Idir' must be specified _without_ any spaces between -I and the directory name -- that is, `-Idir' is valid, but `-I dir' is rejected by the g77 compiler (though the preprocessor supports the latter form). Also note that the general behavior of -I and INCLUDE is pretty much the same as of -I with #include in gcc's C preprocessor, with regard to looking for `header.gcc' files and other such things *SUMMARY OF 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 Use explicit DATA (or other initial-value-setting) statements to initialize local variables and arrays to zero. 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 Use SAVE statements in the appropriate places instead. 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. -fugly* Fix the source code so that -fno-ugly (the default) will work. Note that, for many programs, it is difficult to practically avoid using the features enabled via -fugly-init, and these features pose the lowest risk of writing nonportable code of the various "ugly" features. -fxxx-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 -fxxx-intrinsics-disable. *USER-VISIBLE CHANGES DURING 0.5.x* In 0.5.18: - The BYTE and WORD statements now are supported, to a limited extent. - INTEGER*1, INTEGER*2, INTEGER*8, and their LOGICAL equivalents, now are supported to a limited extent. Among the missing elements are complete intrinsic and constant support. - Support automatic arrays in procedures. For example, `REAL A(N)', where `A' is not a dummy argument, specifies that `A' is an automatic array. The size of `A' is calculated from the value of `N' each time the procedure is called, that amount of space is allocated, and that space is freed when the procedure returns to its caller. - Add `-fno-zeros' option, enabled by default, to reduce compile-time CPU and memory usage for code that provides initial zero values for variables and arrays. - Introduce three new options that apply to all compilations by g77-aware GNU compilers -- -fmove-all-movables, -freduce-all-givs, and -frerun-loop-opt -- which can improve the run-time performance of some programs. - Replace much of the existing documentation (including the file you are reading right now) with a single Info document. - New option -fno-second-underscore. In 0.5.17: - ERF() and ERFC() intrinsics are now generic intrinsics, mapping to ERF/DERF and ERFC/DERFC, respectively -- NOTE: use INTRINSIC ERF,ERFC in any code that might reference these as generic intrinsics, to improve the likelihood of diagnostics (instead of subtle run-time bugs) when using compilers that don't support these as intrinsics - New option -Wsurprising - DO loops with non-INTEGER variables now diagnosed only when -Wsurprising specified (previously diagnosed unless -fpedantic or -fugly specified) In 0.5.16: - libf2c changed to output a leading zero (0) digit for floating-point values output via list-directed and formatted output (to bring g77 more in line with many existing Fortran implementations -- the ANSI FORTRAN 77 standard leaves this choice to the implementation) - libf2c no longer built with debugging info intact, making it much smaller - Automatic installation of `g77' command now works - Diagnostic messages from compiler now more informative, a la gcc, including messages like "In function `foo':" and "In file included from...:" - New group of intrinsics called `unix', including ABORT, DERF, DERFC, ERF, ERFC, EXIT, FLUSH, GETARG, GETENV, SIGNAL, and SYSTEM - -funix-intrinsics-{delete,hide,disable,enable} options introduced - -fno-underscoring option introduced - --driver=COMMAND option introduced to the g77 command - Support for gcc's -fident and -fno-ident options extended to g77 - `g77 -v' returns much more version info, for submitting better bug reports easily (for example -- assuming there are still any bugs left in g77 ;-) - Many improvements to the g77 command to better fulfill its role as a front-end to the gcc driver (e.g. recognition of both `-v' and `--version' instead of just `-v') - Compiling preprocessed (*.F) files now results in better diagnostics and debugging information, as the source-location info now is passed all the way through the compilation process instead of being lost In 0.5.15: - -ffixed-line-length-N option introduced In 0.5.14: - Support for gcc's -I option extended to g77 - -fbackslash option introduced - -fugly-args option enabled by default (allows CALL FOO(4HABCD)) - -fugly-init option introduced - -finit-local-zero option introduced - Support for gcc's -Wimplicit option extended to g77 - -Wall now implies -Wunused and, when -O is specified, -Wuninitialized - Hollerith constants as actual arguments now are passed by reference instead of by value -- so CALL FOO(4HABCD) is now compiled exactly the same as CALL FOO(%REF('ABCD')), instead of as CALL FOO(%VAL('ABCD')) - Hollerith constants converted to larger types now are padded on the right with spaces; converted to smaller types, warnings are issued if non-spaces are truncated on the right - Format specifications of arrays of types other than CHARACTER are allowed in I/O statements, such as when they contain Hollerith data - Typeless constants as actual arguments now are passed by reference to a INTEGER version of the constant instead of by value - Typeless constants converted to larger types are padded on the left with zeros; converted to smaller types, warnings are issued if non-zero bits are truncated on the left - %DESCR() of a non-CHARACTER expression treats the expression as if it were CHARACTER, passing both a pointer to the expression and the length of the type of the expression in bytes, by value, in the "hidden" list of lengths used for CHARACTER arguments - The ICHAR(), IACHAR(), and LEN() intrinsics now accept character expressions involving concatenation of assumed-length dummy arguments - BLOCK DATA program units now can contain NAMELIST, EXTERNAL, INTRINSIC, and VOLATILE statements - Zero-length character expressions now supported - f2c's IMAG() intrinsic now supported - INCLUDE statement restrictions, such as no continuation lines allowed, now lifted *WHAT IS AND ISN'T SUPPORTED* This release supports ANSI FORTRAN 77 with the following caveats: - No passing of an external procedure as an actual argument if the procedure's type is declared CHARACTER*(*) (because it isn't clear the standard really considers this standard-conforming, but it should be fairly easy to support if someone gets an RFI showing it is standard-conforming). - No passing of a dummy procedure as an actual argument if the procedure's type is declared CHARACTER*(*) (again, because it isn't clear the standard considers this conformant). - 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 (this is also disallowed by Fortran 90, as it offers no additional capabilities). Note that it is very unlikely that any existing Fortran code tries to use this unsupported construct. - 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 (this is also required 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 in any case it is very unlikely that any existing Fortran code tries to use this unsupported construct. This release supports ANSI FORTRAN 77 plus: - -g for local variables and external names; COMMON variables, local EQUIVALENCE variables, labels, and so on aren't supported yet. - LOC(), if -funix-intrinsics-enable is in force. - %LOC, %VAL, %REF, and %DESCR -- where %DESCR currently means the same thing as passing the argument as if it was type CHARACTER. - MIL-STD 1753 features (IAND, IOR, MVBITS, DO WHILE, END DO, etc). - NAMELIST. - Most f2c/f77 intrinsics (AND, OR, LSHIFT, RSHIFT, and so on). - DOUBLE COMPLEX and related intrinsics (standard and f2c varieties). - Various Fortran 90 features. - Various DEC VAX/VMS FORTRAN v4.0 features. - Various f2c features. - Source files that are uppercase-only (enforced), lowercase-only (enforced), caseless, and various other combinations as chosen via command-line options. - Arbitrary (limited only by available memory) number of continuation lines. - Use of '&' in column 1 to indicate a continuation line a la f2c. - Dollar signs ('$') in identifiers (other than as the first character) when the command-line option -fdollar-ok is specified. *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 area 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 it is a BLOCK DATA and generates 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). 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. *FORTRAN 90* The -ff90 and -fno-f90 command-line options control whether certain Fortran 90 constructs are recognized. (Other Fortran 90 constructs might or might not be recognized depending on other options such as -fvxt-not-f90, -ff90-intrinsics-enable, and the current level of support for Fortran 90.) When -ff90 is specified, the following constructs are accepted: - REAL(Z), where Z is DOUBLE COMPLEX, as meaning DBLE(Z) instead of the canonical F77 meaning of REAL(REAL(Z)) - Zero-length CHARACTER entities even when -fpedantic specified - Zero-size array dimensions (as in INTEGER I(10,20,4:2)) (not supported by run-time code, so diagnostics are produced for g77 nevertheless). - DOUBLE COMPLEX (explicit or implicit) even when -fpedantic specified. - Substrings of constants (as in "'hello'(3:5)") even when -fpedantic specified. - DATA statements allowed to precede executable statements even when -fpedantic specified (note that this is not the same as whether "DATA I/1/" is permitted before other specifications for I, such as "INTEGER I" -- it does allow, however, "DATA I/1/" before "INTEGER J"). - Semicolon as statement separator even when -fpedantic specified (so "CALL FOO; CALL BAR" works). - Underscores are not accepted as the first character of a symbol name, since F90 provides a different interpretation for certain cases where that would occur (though g77 does not yet support that interpretation). If -fpedantic is specified, the following constructs result in diagnostics: - Use of semicolons on line with INCLUDE statement. *SOURCE CODE FORM* The -ffree-form (aka -fno-fixed-form) and -ffixed-form (aka -fno-free-form) command-line options govern how the source file is interpreted. Fixed form corresponds to classic 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 "R = 3 . 1"). The way a Fortran compiler views source files depends entirely on the implementation choices made for the compiler. GNU Fortran currently tries to be somewhat like a few popular compilers (f2c, DEC Fortran, and so on), though a cleaner default definition along with more flexibility offered by command-line options is likely to be offered with g77-0.6. Here are some facts regarding the way g77 interprets source lines: - 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. - 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' inside character and hollerith constants, but nevertheless seems to treat the column position as if it had been affected by any tab. 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 info to decide how to interpret the length of the line and continued constants. NOTE: this default behavior probably will change for 0.6, when it will presumably be available via a command-line option. The default as of 0.6 is expected to be a "pure visual" model, where tabs are immediately converted to spaces and otherwise have no effect, so the way a typical user sees source lines produces a consistent result no matter how the spacing in those source lines is actually implemented via tabs, spaces, and trailing tabs/spaces before newline. Command-line options are likely to be added to specify whether all or just-tabbed lines are to be extended to 132 or full input-line length, and perhaps even an option will be added to specify the truncated-line behavior to which Digital compilers default. - Source lines shorter than the applicable fixed length are treated as if they were padded with spaces to that length. 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 does not apply to lines that are effectively of infinite length -- such lines are specified using command-line options like -ffixed-line-length-none, for example. *TYPES, SIZES, PRECISIONS, AND CONSTANTS* 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 is offered by the various types such as LOGICAL, INTEGER, REAL, DOUBLE PRECISION, COMPLEX, and CHARACTER. Further, many compilers offer so-called "*N" notation, but the meaning of N varies across compilers and target architectures. The standard requirements are that LOGICAL, INTEGER, and REAL occupy the same amount of storage space, and that COMPLEX and DOUBLE PRECISION take twice as much storage space as REAL. Further, it requires that COMPLEX entities be ordered such that when a COMPLEX variable is EQUIVALENCE'd with a two-element REAL array named R, R(1) corresponds to the real element and R(2) to the imaginary element of the COMPLEX variable. No particular requirements as to precision 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 to the letter, 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 DOUBLE PRECISION on a boundary that is not an even multiple of its size, but still an even multiple of the size of a REAL variable. On some target architectures, using the canonical mapping of Fortran types to underlying architectural types, such placement is prohibited by the machine definition. 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: REAL: same size as whatever gcc calls a "float" DOUBLE PRECISION: same size as whatever floating-point type gcc provides that is twice the size of a "float" (usually a "double") INTEGER: a gcc integral type that is the same storage size as "float" LOGICAL: same size as INTEGER COMPLEX: two REALs DOUBLE COMPLEX: two DOUBLE PRECISIONs numeric-type*N (any type other than CHARACTER, such as INTEGER*2): is N times the size of whatever gcc calls a "char" numeric-type(KIND=N): N=1 for REAL, INTEGER, LOGICAL, COMPLEX; N=2 for DOUBLE PRECISION, DOUBLE COMPLEX, char INTEGER/LOGICAL (*1); N=3 for short INTEGER/LOGICAL (*2); N=4 for long long INTEGER/LOGICAL (*8). [These proposed values might change in the future.] Regarding constants, g77 strictly assigns types to all constants not documented as "typeless" (the typeless constants include things like "Z'1'"). Context is never a determining factor for the type, and hence the interpretation, of a typed constant. Examples: "1" is always type INTEGER, "3.141592653545256234" is always type REAL (even if the additional precision specified is lost, and even when used in a DOUBLE PRECISION context), "1E0" is always type REAL, and "1D0" is always type DOUBLE PRECISION. 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 will not support these dangerous semantics, but 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 well be doing something different than other compilers in this regard. *VAX FORTRAN VERSUS FORTRAN 90* The -fvxt-not-f90 and -ff90-not-vxt command-line options control how g77 interprets certain tokens and constructs that are have different meanings in VAX FORTRAN and Fortran 90. When -ff90-not-vxt is specified, the following interpretations are made: - Double-quote character (") delimits character constant just as does apostrophe ('), rather than beginning an octal constant of INTEGER type. - Exclamation point in column 5 of fixed-form source file treated as a continuation character rather than the beginning of a comment (as it does in any other column). - "TYPE " and "TYPE (), <...>" statements recognized as the Fortran 90 variety, not I/O statements. (However, the F90 variety is _not_ supported, so this really just ensures that g77 will produce a diagnostic instead of trying to implement the VXT TYPE statement -- which currently is not supported as well.) *LIBRARY AND PROCEDURE-CALLING INTERFACE* Currently, -ff2c and -ff2c-library are defaults and -ff2c-library must be in force for g77 to work properly. The -ff2c option specifies that g77 is to generate code that is link-time and run-time compatible with code generated by an version of f2c built to be generally compatible with g77. (This will normally be the case, but it is possible that with older or perhaps even newer versions of f2c, or with certain configuration changes to f2c internals, incompatibilities will nevertheless result.) Specifying -fno-f2c allows g77 to generate, in some cases, faster code. For example, how REAL and [DOUBLE] COMPLEX FUNCTIONs are called is governed by the -ff2c command-line option. With -fno-f2c, they are compiled as returning the appropriate type (float, __complex__ float, __complex__ double), whereas with -ff2c, 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 functions return double, while [DOUBLE] COMPLEX functions return void but have an extra argument pointing to a place for the functions to return their values. (It is possible that in some cases -ff2c might produce faster code. Experiment and enjoy.) An example of the effect of -ff2c-library, which is the default (and currently must be in force, since g77 compiles code for use only with libf2c), is that diagnostics are issued for some features unsupported by the f2c library, such as NAMELIST in combination with source case preservation. *OPTIONS FOR POTENTIALLY BUGGY PROGRAMS* The -finit-local-zero option tells g77 to initialize all local variables and arrays (that are not otherwise explicitly initialized) to binary zeros. Many other compilers do this, 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. Use the -Wuninitialized option (which requires -O as well) to find some such cases. The -fno-automatic command-line option tells g77 to assume, in essence, that a SAVE statement is present in every program unit. The effect of this is that all variables and arrays are made static, i.e. 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. The default is -fautomatic, which tells g77 to try and put variables and arrays on the stack where possible and reasonable. Use the -Wuninitialized option (which requires -O as well), _without_ specifying -fno-automatic, to find some cases where SAVE is erroneously omitted as an attribute for variables and arrays. The -W options tell g77 to warn about various suspicious constructs. In particular, the -Wimplicit, `-O -Wuninitialized', and -Wsurprising options can sometimes identify bugs in programs that appear to work when compiled by other Fortran compilers but do not work when compiled by g77 (or vice versa). *OPTIONS FOR SPEEDING UP PROGRAMS* Aside from the usual gcc options, such as -O, -ffast-math, and so on (see the gcc documentation), consider trying: -fno-f2c, if you aren't linking with any f2c-produced code (other than libf2c) If you're using -fno-automatic already, you probably should change your code to allow compilation with -fautomatic, because the program should run faster. Similarly, you should be able to use -fno-init-local-zero 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 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 (e.g. via -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 *SUMMARY OF 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. *PEDANTIC COMPILATION* The -fpedantic and -fno-pedantic command-line options control whether certain non-standard constructs elicit diagnostics (usually in the form of warnings) from g77. The -fpedantic option 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 -ff90 in force along with -fpedantic, some constructs are accepted that result in diagnostics when -fno-f90 and -fpedantic are both in force. See *FORTRAN 90* for information on those constructs. The constructs for which g77 issues diagnostics when -fpedantic is specified (and -fno-f90 is in force) are: - "READ (), " -- the standard disallows the comma here, while allowing it in "READ [, ]", but many compilers (including f2c) support the superfluous comma. - DOUBLE COMPLEX, either explicitly (via explicit or IMPLICIT statement) or implicitly (as in "C*D", where C is COMPLEX and D is DOUBLE PRECISION, which is prohibited by the standard because it should produce a non-standard DOUBLE COMPLEX result). - Automatic conversion of LOGICAL, REAL, DOUBLE PRECISION, and COMPLEX expressions to INTEGER 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, <...>)"); 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 context such as: arithmetic IF (where COMPLEX expressions are completely disallowed). - Substring operators applied to character constants and named constants (such as "PRINT *,'hello'(3:5)", which would print "llo"). - Null argument passed to statement function (as in "PRINT *,FOO(,3)"). - Differences between 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). - Differences between named-COMMON-block sizes between program units. - Specification statements following first DATA statement (normally "DATA I/1/" may be followed by "INTEGER J", though not "INTEGER I", but -fpedantic complains about both cases). - Semicolon as statement separator (as in "CALL FOO; CALL BAR"). - Comma before list of I/O items in WRITE, ENCODE, DECODE, REWRITE statements (kind of strange, since ENCODE/DECODE/REWRITE should yield diagnostics with -fpedantic???), as with READ (as explained above). - Use of '&' in column 1 of fixed-form source (indicates continuation). - Use of CHARACTER constants to initialize numeric entities, and vice versa. - Expressions having two arithmetic operators in a row, such as "X*-Y". *UGLY FEATURES* The -fugly and -fno-ugly 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. The constructs enabled via -fugly include: - 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 typeless and hollerith constants in non-standard places (the "standard" here being the appendix in ANSI FORTRAN 77 and the descriptions in MIL-STD 1753), plus in places controlled by -fugly-args and -fugly-init. - Use of LOGICAL variable in ASSIGN and assigned-GOTO statements. - Single trailing comma meaning "pass extra trailing null argument" in list of actual arguments to procedure other than statement function (e.g. "CALL FOO(,)" meaning "pass two null arguments" rather than "pass one null argument"). As of 0.5.11, the -fugly-args and -fno-ugly-args options are available. The construct enabled via -fugly-args is one of those enabled via -fugly, and is: - Passing of typeless and hollerith constants as actual arguments in procedure invocations As of 0.5.14, the -fugly-init and -fno-ugly-init options are available. The set of constructs enabled via -fugly-init is a subset of those enabled via -fugly, and is: - Use of hollerith and typeless constants in contexts where they set initial (compile-time) values for variables, arrays, and named constants -- i.e. DATA and PARAMETER statements, plus type-declaration statements specifying initial values - In the same contexts as above, use of character constants to initialize numeric items and vice versa (one constant per item) - Use of hollerith and typeless constants on the right-hand side of assignment statements to numeric types The defaults are "-fugly-args -fugly-init". Note that specifying -fugly or -fno-ugly affects all related options, so that "-fugly-args -fno-ugly -fugly-init" would leave only -fugly-init in effect. *CASE SENSITIVITY IN SOURCE CODE* 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. Low-level switches are identified in this discussion thusly: 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 will eventually support NAMELIST in a manner that is coordinate with these source switches, in 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 via the f2c library, 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 g77lib is written), but that seems to be overkill for a product in alpha (or even 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 for the stand-alone front end (ffe): 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 whereas 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). *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. If a group is deleted, no intrinsics will be recognized as belonging to that group; if it is disabled, intrinsics will be recognized as belonging to the group but cannot be referenced (other than via the INTRINSIC statement) through that group; if hidden, intrinsics in that group are recognized and enabled (if implemented) only if the first mention of the actual name of an intrinsic is in an INTRINSIC statement; if 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, the above program unit will be compiled with errors, 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, etc. The groups are: DCP -- DOUBLE COMPLEX intrinsics from the standards (F77, F90) 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 (as of V4) intrinsics The command-line options are: -fdcp-intrinsics-delete -- Delete DCP intrinsics -fdcp-intrinsics-hide -- Hide DCP intrinsics -fdcp-intrinsics-disable -- Disable DCP intrinsics -fdcp-intrinsics-enable -- Enable DCP intrinsics -ff2c-intrinsics-delete -- Delete F2C intrinsics -ff2c-intrinsics-hide -- Hide F2C intrinsics -ff2c-intrinsics-disable -- Disable F2C intrinsics -ff2c-intrinsics-enable -- Enable F2C intrinsics -ff90-intrinsics-delete -- Delete F90 intrinsics -ff90-intrinsics-hide -- Hide F90 intrinsics -ff90-intrinsics-disable -- Disable F90 intrinsics -ff90-intrinsics-enable -- Enable F90 intrinsics -fmil-intrinsics-delete -- Delete MIL intrinsics -fmil-intrinsics-hide -- Hide MIL intrinsics -fmil-intrinsics-disable -- Disable MIL intrinsics -fmil-intrinsics-enable -- Enable MIL intrinsics -funix-intrinsics-delete -- Delete UNIX intrinsics -funix-intrinsics-hide -- Hide UNIX intrinsics -funix-intrinsics-disable -- Disable UNIX intrinsics -funix-intrinsics-enable -- Enable UNIX intrinsics -fvxt-intrinsics-delete -- Delete VXT intrinsics -fvxt-intrinsics-hide -- Hide VXT intrinsics -fvxt-intrinsics-disable -- Disable VXT intrinsics -fvxt-intrinsics-enable -- Enable VXT intrinsics *TROUBLE (BUGS, ETC.)* First, read the documentation provided with gcc on bugs. In particular, read the sections entitled "Trouble" and "Bugs". Follow this information along with the information listed below. Send bug reports for GNU Fortran to `fortran@gnu.ai.mit.edu'. If you want quicker response to bugs or other needs you have regarding g77, 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 GNU CC distribution. To find out about existing bugs and ongoing plans for GNU Fortran, on Internet do `finger -l fortran@gnu.ai.mit.edu' or whatever is the equivalent on your system. (You might need to use the address `fortran@gate-1.gnu.ai.mit.edu' instead, or use gate-2, gate-3, gate-4, etc. instead of gate-1.) Alternatively, retrieve `gnu.ai.mit.edu:/g77.plan' via anonymous ftp, or if you cannot do that, email `fortran@gnu.ai.mit.edu' asking for a recent copy of the GNU Fortran .plan file. (The `finger' command shown above obtains the most recent copy of all these methods.) For all g77 bug reports, enclose the version and configuration info for g77. As of version 0.5.16, an easy way to do this is to issue the command `g77 -v' and include the output with the bug report -- ignore any error messages that are displayed when the linker is run. (Prior to version 0.5.16, an actual Fortran source file needed to be compiled to get the various Fortran-specific portions of the g77 product to be invoked and thus display their version numbers. 0.5.16 has changes to the g77 command to make this process automatic when `-v' is specified without additional options specifying actions other than displaying the version info. NOTE: Version 0.5.16 had a bug in `g77 -v' that resulted in the removal of the system's `/dev/null' file if the command was issued while logged in as `root'. Version 0.5.17 fixes this bug. You might want to use `ls -l /dev/null /dev/zero' to make sure the entry for `null' is similar to that for `zero' and, if not, contact your system administrator about using `mknod' to recreate `/dev/null'.) Note that you should include with your bug report any files INCLUDEd by the source file you send, and any files they INCLUDE, and so on. This is just an extension of the explanation the gcc documentation offers about having to provide the contents of #include'd files. Diagnostics produced by g77 that you do not understand or expect are not necessarily g77 bugs. They might indicate problems with your code that, perhaps, no other compiler has found. Please check out your code thoroughly, and read applicable g77 documentation, before assuming g77 has a bug in this area. 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 `-lf2c -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, because some systems need it and g77 doesn't do it automatically. If your program successfully compiles and links, but doesn't work, either producing incorrect results or crashing, there are various things you can try. Among the things you should try with your code before giving up, or assuming g77 or libf2c must have a bug, are the following: - Compile all your Fortran code with `-O -W -Wall -Wimplicit' and make sure all the resulting warnings are ones you expect and understand. - Try using f2c instead of g77 to compile all your code, using the -C option with f2c (which checks array bounds -- g77 doesn't have such an option yet, which is why you have to use f2c), and link and run the resulting program trying to reproduce the bug. If a run-time bug occurs both when your program is compiled with g77 and when compiled with f2c, that suggests (but does not prove) that the bug is not in g77, rather that it is either in your own code (quite likely), in libf2c, in gcc, or elsewhere. Probably 99% of the time the bug is in your own code, EVEN IN CASES WHERE YOUR OWN CODE "WORKS" WITH OTHER COMPILERS. Please follow the instructions above to try and find bugs in your code before submitting bug reports. Some causes for run-time problems that might be invisible in the code when using g77: - It is possible that combining code compiled with f2c and with g77 results in misbehaving programs. This can happen if, for example, f2c's view of the system configuration, and especially if the copy of f2c.h used when compiling the output of f2c, don't agree with g77's configuration and the f2c.h used when compiling its version of libf2c. Another way bugs might happen is if you don't use the same, or a similar enough, version of gcc to compile f2c's output as is integrated with the version of g77 you're using. The solution is to try compiling all Fortran code in your program with the exact same compiler configuration. Try using f2c with gcc exclusively, for example. Then try using g77 exclusively. See what works and what doesn't, and perhaps that'll help you identify the source of the problem. Note that "Fortran code" includes not only your own Fortran code, but any libraries you are using that were either written in Fortran or were designed to interface to some Fortran system. A third- party Fortran library might not have been compiled with a version of g77 compatible with the one you're using, for example -- to fix this, you need to obtain an appropriate version of the library. - If you use -fno-f2c when compiling some, but not all, code, there could easily be run-time errors. If functions returning REAL, COMPLEX, or DOUBLE COMPLEX are compiled and invoked from different "sets" of code (where one "set" is compiled with -fno-f2c, and the other set isn't), there almost certainly will be run-time bugs. (If you want to try running gdb on the g77 compiler itself, named f771, note that the global variables lineno and input_filename usually are accurate for most kinds of crashes, and the presence of an invocation of ffestd_exec_end() on the stack indicates that f771 was in the second pass of processing a program unit instead of the first pass. This might help you fix the bug or find a temporary workaround -- the fix and the information should be sent in addition to the bug report.) *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 the Fortran language that f2c doesn't. However, f2c offers a few that g77 doesn't, like INTEGER*2. It is expected that g77 will offer some or all of these missing features at some time in the future. Compiler Options ---------------- g77 offers a whole bunch of compiler options that f2c doesn't. However, f2c offers a few that g77 doesn't, like an option to generate code to check array subscripts at run time. It is expected that g77 will offer some or all of these missing options 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 noticably faster compiling many Fortran source files than using f2c in conjunction with gcc. Optimization (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|gcc can generate code that is faster than g77. 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+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;" since 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). However, due to apparent bugs in the back end, g77 currently doesn't take advantage of this facility at all -- it doesn't emit any debugging information for COMMON and EQUIVALENCE areas, other than information on the array of `char' it creates (and, in the case of local EQUIVALENCE, names) for each such area. 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. 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. *DISAPPOINTMENTS AND MISUNDERSTANDINGS* (Make sure you've read the same-titled section in the gcc docs first!) - g77 does not allow REAL and other weird types for arguments to intrinsics like AND, OR, and SHIFT. - g77 rejects some particularly nonportable, silent data-type conversions such as LOGICAL to REAL (as in "A=.FALSE." where A is REAL) that other compilers might quietly accept. Some such conversions are accepted when various forms of the -fugly option are specified, however. - g77 defaults to specially processing backslashes (\) in character and hollerith constants a la the C language. Despite not being within the spirit (though emphatically within the letter) of the ANSI FORTRAN 77 standard, g77 defaults to this because that is what f77 defaults to, and apparently lots of code depends on this feature. You can always specify -fno-backslash to turn off this processing. Because of this, and because of other limitations g77 currently has (like not accepting "PARAMETER (C=CHAR(7))"), the g77 default will remain -fbackslash, and as the expectation of ongoing compatibility is likely to increase, this is likely to never change (unless popular competing implementations of UNIX `f77' commands change their defaults first). - g77 rejects things other compilers accept, like "INTRINSIC SIN,SIN". 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 (unless -fpedantic is specified). In the meantime, you might as well fix your code to be more standard-conforming and portable. - g77 disallows IMPLICIT CHARACTER*(*). This is not standard-conforming, and there are some very good reasons for that. When I next remember any, I'll try to write them down. - 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). - g77 doesn't support pointers or allocatable objects. This stuff is probably considered just behind INTEGER*2 on the list of large, important things to add to g77. - 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. - 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, and in particular requires a great deal of work either upgrading or replacing libf2c. - g77 doesn't support various OPEN, CLOSE, and INQUIRE keywords such as "DISP='DELETE'". These extensions are easy to add to g77 itself but require work upgrading or replacing libf2c. - 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.) - g77 doesn't allow, e.g., "CALL IFIX". 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. Use "EXTERNAL IFIX" to call a user-written IFIX subroutine. - g77 doesn't allow intrinsics in PARAMETER statements. See gcc/f/PROJECTS. This is a feature I consider to be absolutely vital, even though it is not standard-conforming. - 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 follow suit by adding this feature. - g77 doesn't support "FORMAT(I)" and the like. See the answer for not supporting STRUCTURE, UNION, RECORD, and MAP. *OPEN QUESTIONS* Please consider offering useful answers to these! - g77 treats constants like Z'ABCD' and 'ABCD'Z as typeless. It seems like maybe the prefix-letter form, Z'ABCD', should be INTEGER instead. Perhaps this will be changed for 0.6. - 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? *INTERFACING, DEBUGGING, ETC.* GNU Fortran currently generates code that is object-compatible with the f2c converter. Also, it avoids limitations in the current GNU Back End (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. NOTE: 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. 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, i.e. 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 command-line 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. 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. Therefore, given Max_Cost = 0 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 -- 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, given the statement Foo = 3.14159 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, for example. 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 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. Main Program Unit (The PROGRAM Statement) ----------------------------------------- When g77 compiles a main program unit, it gives it the public procedure name `MAIN__'. The libf2c 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 libf2c 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-0.5.16 includes a bug fix for libf2c 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 libf2c, found in the source file gcc/f/runtime/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, libf2c's main() sets up the information used by the IARGC() and GETARG() intrinsics. Bypassing libf2c'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 libf2c 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. 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. Arrays (The DIMENSION Statement) -------------------------------- 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 ajacent 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). 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 non-zero 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. Procedures (The SUBROUTINE, FUNCTION, and ENTRY Statements) ----------------------------------------------------------- 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 gcc/f/runtime/f2c.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 `__g77_length_X' 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 `__g77_length_X' arguments are appended in the order they 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 this discussion applies to CHARACTER variables and arrays _only_. It does _not_ apply to external CHARACTER functions or to intrinsic CHARACTER functions. That is, no second `__g77_length_X' 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. Adjustable Arrays (The DIMENSION Statement) ------------------------------------------- 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, given 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 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 the 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!) Subroutines (The SUBROUTINE and ENTRY Statements) ------------------------------------------------- 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 function), and the callee just returns whatever integer is specified in the RETURN statement for the subroutine (e.g. "RETURN 1" is implemented as "X = 1" followed by "RETURN" in C, and "RETURN" by itself is "X = 0" and "RETURN"). Functions (The FUNCTION and ENTRY Statements) --------------------------------------------- g77 handles in a special way functions that return the following types: - CHARACTER - COMPLEX (and DOUBLE COMPLEX) - REAL 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 and DOUBLE 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 gcc's `__complex__ float /* or double */' function, returning the result of the function in the same way as gcc would. For REAL, when -ff2c is in force, g77 implements a function that actually returns DOUBLE PRECISION (usually C's `double' type). When -fno-f2c is in force, REAL functions return `float'. Common Blocks (The COMMON Statement) ------------------------------------ g77 names and lays out COMMON areas the same way f2c does, for compatibility with f2c. Currently, g77 does not emit any debugging information for items in a COMMON area, due to an apparent bug in the GBE. Moreover, g77 will implement a COMMON area such that its type will be an array of the C `char' data type. So, when debugging, you must know the offset into a COMMON area for a particular item in that area, and you have to take into account the appropriate multiplier for the respective sizes of the types (as declared in your code) for the items preceding the item in question as compared to the size of the `char' type. For example, using default implicit typing, the statement COMMON I(15),R(20),T will result in a public 144-byte `char' array named `_BLNK__' with I placed at _BLNK__[0], R at _BLNK__[60], and T at _BLNK__[140]. (This is assuming that the target machine for the compilation has 4-byte INTEGER and REAL types.) Local Equivalence Areas (The EQUIVALENCE Statement) --------------------------------------------------- g77 treats equivalence 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. Currently, g77 does not emit any debugging information for items in a local EQUIVALENCE area, due to an apparent bug in the GBE. Moreover, g77 will implement a local EQUIVALENCE area such that its type will be an array of the C `char' data type. The name g77 gives this array of `char' type is `__g77_equiv_X', where X is the name of the first item listed in the EQUIVALENCE statements for that area that is placed at the beginning (offset 0) of this array. When debugging, you must therefore access members of EQUIVALENCE areas by specifying the appropriate __g77_equiv_X array section with the appropriate offset. See the explanation of debugging COMMON blocks for info applicable to debugging local EQUIVALENCE areas. (NOTE: g77 version 0.5.16 fixed a bug in how certain EQUIVALENCE cases were handled. The bug caused the debugger to not know the size of the array if any variable or array in the EQUIVALENCE was given an initial value via DATA or similar.) Alternate Entry Points (The ENTRY Statement) -------------------------------------------- The GNU Back End (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'). 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 (currently either COMPLEX or DOUBLE COMPLEX); 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. Assigned Statement Labels (The ASSIGN and GOTO Statements) ---------------------------------------------------------- For portability to machines where a pointer (such as to a label, which is how g77 implements ASSIGN and its cousin, the assigned GOTO) is wider (bitwise) than an INTEGER, g77 does not necessarily use the same memory location to hold the ASSIGNed value of an variable as it does the numerical value in that variable unless the variable is wide enough (can hold enough bits). In particular, while g77 will implement I = 10 as, in C notation, "i = 10;", it might implement 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 might 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", then g77 has decided it can store the pointer to the label directly into "I" itself. (Currently g77 always chooses to make the separate variable, to improve the likelihood that `-O -Wuninitialized' will diagnose failures to do things like "GOTO I" without "ASSIGN 10 TO I" despite doing "I=5".)