This is Info file f/g77.info, produced by Makeinfo-1.64 from the input file /stage/languages/local/gcc/egcs-1.0.2/gcc/f/g77.texi. This file explains how to use the GNU Fortran system. Published by the Free Software Foundation 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA Copyright (C) 1995-1997 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled "GNU General Public License," "Funding for Free Software," and "Protect Your Freedom--Fight `Look And Feel'" are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the sections entitled "GNU General Public License," "Funding for Free Software," and "Protect Your Freedom--Fight `Look And Feel'", and this permission notice, may be included in translations approved by the Free Software Foundation instead of in the original English. Contributed by James Craig Burley (burley@gnu.org). Inspired by a first pass at translating `g77-0.5.16/f/DOC' that was contributed to Craig by David Ronis (ronis@onsager.chem.mcgill.ca). Fortran Programming * g77: (g77). The GNU Fortran compilation system.  File: g77.info, Node: Run-time Library Errors, Prev: Assigned Statement Labels, Up: Debugging and Interfacing Run-time Library Errors ======================= The `libf2c' library currently has the following table to relate error code numbers, returned in `IOSTAT=' variables, to messages. This information should, in future versions of this document, be expanded upon to include detailed descriptions of each message. In line with good coding practices, any of the numbers in the list below should *not* be directly written into Fortran code you write. Instead, make a separate `INCLUDE' file that defines `PARAMETER' names for them, and use those in your code, so you can more easily change the actual numbers in the future. The information below is culled from the definition of `F_err' in `f/runtime/libI77/err.c' in the `g77' source tree. 100: "error in format" 101: "illegal unit number" 102: "formatted io not allowed" 103: "unformatted io not allowed" 104: "direct io not allowed" 105: "sequential io not allowed" 106: "can't backspace file" 107: "null file name" 108: "can't stat file" 109: "unit not connected" 110: "off end of record" 111: "truncation failed in endfile" 112: "incomprehensible list input" 113: "out of free space" 114: "unit not connected" 115: "read unexpected character" 116: "bad logical input field" 117: "bad variable type" 118: "bad namelist name" 119: "variable not in namelist" 120: "no end record" 121: "variable count incorrect" 122: "subscript for scalar variable" 123: "invalid array section" 124: "substring out of bounds" 125: "subscript out of bounds" 126: "can't read file" 127: "can't write file" 128: "'new' file exists" 129: "can't append to file" 130: "non-positive record number" 131: "I/O started while already doing I/O"  File: g77.info, Node: Collected Fortran Wisdom, Next: Trouble, Prev: Debugging and Interfacing, Up: Top Collected Fortran Wisdom ************************ Most users of `g77' can be divided into two camps: * Those writing new Fortran code to be compiled by `g77'. * Those using `g77' to compile existing, "legacy" code. Users writing new code generally understand most of the necessary aspects of Fortran to write "mainstream" code, but often need help deciding how to handle problems, such as the construction of libraries containing `BLOCK DATA'. Users dealing with "legacy" code sometimes don't have much experience with Fortran, but believe that the code they're compiling already works when compiled by other compilers (and might not understand why, as is sometimes the case, it doesn't work when compiled by `g77'). The following information is designed to help users do a better job coping with existing, "legacy" Fortran code, and with writing new code as well. * Menu: * Advantages Over f2c:: If `f2c' is so great, why `g77'? * Block Data and Libraries:: How `g77' solves a common problem. * Loops:: Fortran `DO' loops surprise many people. * Working Programs:: Getting programs to work should be done first. * Overly Convenient Options:: Temptations to avoid, habits to not form. * Faster Programs:: Everybody wants these, but at what cost?  File: g77.info, Node: Advantages Over f2c, Next: Block Data and Libraries, Up: Collected Fortran Wisdom 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. * Menu: * Language Extensions:: Features used by Fortran code. * Compiler Options:: Features helpful during development. * Compiler Speed:: Speed of the compilation process. * Program Speed:: Speed of the generated, optimized code. * Ease of Debugging:: Debugging ease-of-use at the source level. * Character and Hollerith Constants:: A byte saved is a byte earned.  File: g77.info, Node: Language Extensions, Next: Compiler Options, Up: Advantages Over f2c Language Extensions ------------------- `g77' offers several extensions to the Fortran language that `f2c' doesn't. However, `f2c' offers a few that `g77' doesn't, like fairly complete support for `INTEGER*2'. It is expected that `g77' will offer some or all of these missing features at some time in the future. (Version 0.5.18 of `g77' offers some rudimentary support for some of these features.)  File: g77.info, Node: Compiler Options, Next: Compiler Speed, Prev: Language Extensions, Up: Advantages Over f2c 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.  File: g77.info, Node: Compiler Speed, Next: Program Speed, Prev: Compiler Options, Up: Advantages Over f2c Compiler Speed -------------- Saving the steps of writing and then rereading C code is a big reason why `g77' should be able to compile code much faster than using `f2c' in conjunction with the equivalent invocation of `gcc'. However, due to `g77''s youth, lots of self-checking is still being performed. As a result, this improvement is as yet unrealized (though the potential seems to be there for quite a big speedup in the future). It is possible that, as of version 0.5.18, `g77' is noticeably faster compiling many Fortran source files than using `f2c' in conjunction with `gcc'.  File: g77.info, Node: Program Speed, Next: Ease of Debugging, Prev: Compiler Speed, Up: Advantages Over f2c Program Speed ------------- `g77' has the potential to better optimize code than `f2c', even when `gcc' is used to compile the output of `f2c', because `f2c' must necessarily translate Fortran into a somewhat lower-level language (C) that cannot preserve all the information that is potentially useful for optimization, while `g77' can gather, preserve, and transmit that information directly to the GBE. For example, `g77' implements `ASSIGN' and assigned `GOTO' using direct assignment of pointers to labels and direct jumps to labels, whereas `f2c' maps the assigned labels to integer values and then uses a C `switch' statement to encode the assigned `GOTO' statements. However, as is typical, theory and reality don't quite match, at least not in all cases, so it is still the case that `f2c' plus `gcc' can generate code that is faster than `g77'. Version 0.5.18 of `g77' offered default settings and options, via patches to the `gcc' back end, that allow for better program speed, though some of these improvements also affected the performance of programs translated by `f2c' and then compiled by `g77''s version of `gcc'. Version 0.5.20 of `g77' offers further performance improvements, at least one of which (alias analysis) is not generally applicable to `f2c' (though `f2c' could presumably be changed to also take advantage of this new capability of the `gcc' back end, assuming this is made available in an upcoming release of `gcc').  File: g77.info, Node: Ease of Debugging, Next: Character and Hollerith Constants, Prev: Program Speed, Up: Advantages Over f2c Ease of Debugging ----------------- Because `g77' compiles directly to assembler code like `gcc', instead of translating to an intermediate language (C) as does `f2c', support for debugging can be better for `g77' than `f2c'. However, although `g77' might be somewhat more "native" in terms of debugging support than `f2c' plus `gcc', there still are a lot of things "not quite right". Many of the important ones should be resolved in the near future. For example, `g77' doesn't have to worry about reserved names like `f2c' does. Given `FOR = WHILE', `f2c' must necessarily translate this to something *other* than `for = while;', because C reserves those words. However, `g77' does still uses things like an extra level of indirection for `ENTRY'-laden procedures--in this case, because the back end doesn't yet support multiple entry points. Another example is that, given COMMON A, B EQUIVALENCE (B, C) the `g77' user should be able to access the variables directly, by name, without having to traverse C-like structures and unions, while `f2c' is unlikely to ever offer this ability (due to limitations in the C language). 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. In fairness, `g77' could do many of the things `f2c' does to get things working at least as well as `f2c'--for now, the developers prefer making `g77' work the way they think it is supposed to, and finding help improving the other products (the back end of `gcc'; `gdb'; and so on) to get things working properly.  File: g77.info, Node: Character and Hollerith Constants, Prev: Ease of Debugging, Up: Advantages Over f2c 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'.  File: g77.info, Node: Block Data and Libraries, Next: Loops, Prev: Advantages Over f2c, Up: Collected Fortran Wisdom Block Data and Libraries ======================== To ensure that block data program units are linked, especially a concern when they are put into libraries, give each one a name (as in `BLOCK DATA FOO') and make sure there is an `EXTERNAL FOO' statement in every program unit that uses any common block initialized by the corresponding `BLOCK DATA'. `g77' currently compiles a `BLOCK DATA' as if it were a `SUBROUTINE', that is, it generates an actual procedure having the appropriate name. The procedure does nothing but return immediately if it happens to be called. For `EXTERNAL FOO', where `FOO' is not otherwise referenced in the same program unit, `g77' assumes there exists a `BLOCK DATA FOO' in the program and ensures that by generating a reference to it so the linker will make sure it is present. (Specifically, `g77' outputs in the data section a static pointer to the external name `FOO'.) The implementation `g77' currently uses to make this work is one of the few things not compatible with `f2c' as currently shipped. `f2c' currently does nothing with `EXTERNAL FOO' except issue a warning that `FOO' is not otherwise referenced, and for `BLOCK DATA FOO', f2c doesn't generate a dummy procedure with the name `FOO'. The upshot is that you shouldn't mix `f2c' and `g77' in this particular case. If you use f2c to compile `BLOCK DATA FOO', then any `g77'-compiled program unit that says `EXTERNAL FOO' will result in an unresolved reference when linked. If you do the opposite, then `FOO' might not be linked in under various circumstances (such as when `FOO' is in a library, or you're using a "clever" linker--so clever, it produces a broken program with little or no warning by omitting initializations of global data because they are contained in unreferenced procedures). The changes you make to your code to make `g77' handle this situation, however, appear to be a widely portable way to handle it. That is, many systems permit it (as they should, since the FORTRAN 77 standard permits `EXTERNAL FOO' when `FOO' is a block data program unit), and of the ones that might not link `BLOCK DATA FOO' under some circumstances, most of them appear to do so once `EXTERNAL FOO' is present in the appropriate program units. Here is the recommended approach to modifying a program containing a program unit such as the following: BLOCK DATA FOO COMMON /VARS/ X, Y, Z DATA X, Y, Z / 3., 4., 5. / END If the above program unit might be placed in a library module, then ensure that every program unit in every program that references that particular `COMMON' area uses the `EXTERNAL' statement to force the area to be initialized. For example, change a program unit that starts with INTEGER FUNCTION CURX() COMMON /VARS/ X, Y, Z CURX = X END so that it uses the `EXTERNAL' statement, as in: INTEGER FUNCTION CURX() COMMON /VARS/ X, Y, Z EXTERNAL FOO CURX = X END That way, `CURX' is compiled by `g77' (and many other compilers) so that the linker knows it must include `FOO', the `BLOCK DATA' program unit that sets the initial values for the variables in `VAR', in the executable program.  File: g77.info, Node: Loops, Next: Working Programs, Prev: Block Data and Libraries, Up: Collected Fortran Wisdom Loops ===== The meaning of a `DO' loop in Fortran is precisely specified in the Fortran standard...and is quite different from what many programmers might expect. In particular, Fortran `DO' loops are implemented as if the number of trips through the loop is calculated *before* the loop is entered. The number of trips for a loop is calculated from the START, END, and INCREMENT values specified in a statement such as: DO ITER = START, END, INCREMENT The trip count is evaluated using a fairly simple formula based on the three values following the `=' in the statement, and it is that trip count that is effectively decremented during each iteration of the loop. If, at the beginning of an iteration of the loop, the trip count is zero or negative, the loop terminates. The per-loop-iteration modifications to ITER are not related to determining whether to terminate the loop. There are two important things to remember about the trip count: * It can be *negative*, in which case it is treated as if it was zero--meaning the loop is not executed at all. * The type used to *calculate* the trip count is the same type as ITER, but the final calculation, and thus the type of the trip count itself, always is `INTEGER(KIND=1)'. These two items mean that there are loops that cannot be written in straightforward fashion using the Fortran `DO'. For example, on a system with the canonical 32-bit two's-complement implementation of `INTEGER(KIND=1)', the following loop will not work: DO I = -2000000000, 2000000000 Although the START and END values are well within the range of `INTEGER(KIND=1)', the *trip count* is not. The expected trip count is 40000000001, which is outside the range of `INTEGER(KIND=1)' on many systems. Instead, the above loop should be constructed this way: I = -2000000000 DO IF (I .GT. 2000000000) EXIT ... I = I + 1 END DO The simple `DO' construct and the `EXIT' statement (used to leave the innermost loop) are F90 features that `g77' supports. Some Fortran compilers have buggy implementations of `DO', in that they don't follow the standard. They implement `DO' as a straightforward translation to what, in C, would be a `for' statement. Instead of creating a temporary variable to hold the trip count as calculated at run time, these compilers use the iteration variable ITER to control whether the loop continues at each iteration. The bug in such an implementation shows up when the trip count is within the range of the type of ITER, but the magnitude of `ABS(END) + ABS(INCR)' exceeds that range. For example: DO I = 2147483600, 2147483647 A loop started by the above statement will work as implemented by `g77', but the use, by some compilers, of a more C-like implementation akin to for (i = 2147483600; i <= 2147483647; ++i) produces a loop that does not terminate, because `i' can never be greater than 2147483647, since incrementing it beyond that value overflows `i', setting it to -2147483648. This is a large, negative number that still is less than 2147483647. Another example of unexpected behavior of `DO' involves using a nonintegral iteration variable ITER, that is, a `REAL' variable. Consider the following program: DATA BEGIN, END, STEP /.1, .31, .007/ DO 10 R = BEGIN, END, STEP IF (R .GT. END) PRINT *, R, ' .GT. ', END, '!!' PRINT *,R 10 CONTINUE PRINT *,'LAST = ',R IF (R .LE. END) PRINT *, R, ' .LE. ', END, '!!' END A C-like view of `DO' would hold that the two "exclamatory" `PRINT' statements are never executed. However, this is the output of running the above program as compiled by `g77' on a GNU/Linux ix86 system: .100000001 .107000001 .114 .120999999 ... .289000005 .296000004 .303000003 LAST = .310000002 .310000002 .LE. .310000002!! Note that one of the two checks in the program turned up an apparent violation of the programmer's expectation--yet, the loop is correctly implemented by `g77', in that it has 30 iterations. This trip count of 30 is correct when evaluated using the floating-point representations for the BEGIN, END, and INCR values (.1, .31, .007) on GNU/Linux ix86 are used. On other systems, an apparently more accurate trip count of 31 might result, but, nevertheless, `g77' is faithfully following the Fortran standard, and the result is not what the author of the sample program above apparently expected. (Such other systems might, for different values in the `DATA' statement, violate the other programmer's expectation, for example.) Due to this combination of imprecise representation of floating-point values and the often-misunderstood interpretation of `DO' by standard-conforming compilers such as `g77', use of `DO' loops with `REAL' iteration variables is not recommended. Such use can be caught by specifying `-Wsurprising'. *Note Warning Options::, for more information on this option.  File: g77.info, Node: Working Programs, Next: Overly Convenient Options, Prev: Loops, Up: Collected Fortran Wisdom Working Programs ================ Getting Fortran programs to work in the first place can be quite a challenge--even when the programs already work on other systems, or when using other compilers. `g77' offers some facilities that might be useful for tracking down bugs in such programs. * Menu: * Not My Type:: * Variables Assumed To Be Zero:: * Variables Assumed To Be Saved:: * Unwanted Variables:: * Unused Arguments:: * Surprising Interpretations of Code:: * Aliasing Assumed To Work:: * Output Assumed To Flush:: * Large File Unit Numbers::  File: g77.info, Node: Not My Type, Next: Variables Assumed To Be Zero, Up: Working Programs Not My Type ----------- A fruitful source of bugs in Fortran source code is use, or mis-use, of Fortran's implicit-typing feature, whereby the type of a variable, array, or function is determined by the first character of its name. Simple cases of this include statements like `LOGX=9.227', without a statement such as `REAL LOGX'. In this case, `LOGX' is implicitly given `INTEGER(KIND=1)' type, with the result of the assignment being that it is given the value `9'. More involved cases include a function that is defined starting with a statement like `DOUBLE PRECISION FUNCTION IPS(...)'. Any caller of this function that does not also declare `IPS' as type `DOUBLE PRECISION' (or, in GNU Fortran, `REAL(KIND=2)') is likely to assume it returns `INTEGER', or some other type, leading to invalid results or even program crashes. The `-Wimplicit' option might catch failures to properly specify the types of variables, arrays, and functions in the code. However, in code that makes heavy use of Fortran's implicit-typing facility, this option might produce so many warnings about cases that are working, it would be hard to find the one or two that represent bugs. This is why so many experienced Fortran programmers strongly recommend widespread use of the `IMPLICIT NONE' statement, despite it not being standard FORTRAN 77, to completely turn off implicit typing. (`g77' supports `IMPLICIT NONE', as do almost all FORTRAN 77 compilers.) Note that `-Wimplicit' catches only implicit typing of *names*. It does not catch implicit typing of expressions such as `X**(2/3)'. Such expressions can be buggy as well--in fact, `X**(2/3)' is equivalent to `X**0', due to the way Fortran expressions are given types and then evaluated. (In this particular case, the programmer probably wanted `X**(2./3.)'.)  File: g77.info, Node: Variables Assumed To Be Zero, Next: Variables Assumed To Be Saved, Prev: Not My Type, Up: Working Programs Variables Assumed To Be Zero ---------------------------- Many Fortran programs were developed on systems that provided automatic initialization of all, or some, variables and arrays to zero. As a result, many of these programs depend, sometimes inadvertently, on this behavior, though to do so violates the Fortran standards. You can ask `g77' for this behavior by specifying the `-finit-local-zero' option when compiling Fortran code. (You might want to specify `-fno-automatic' as well, to avoid code-size inflation for non-optimized compilations.) Note that a program that works better when compiled with the `-finit-local-zero' option is almost certainly depending on a particular system's, or compiler's, tendency to initialize some variables to zero. It might be worthwhile finding such cases and fixing them, using techniques such as compiling with the `-O -Wuninitialized' options using `g77'.  File: g77.info, Node: Variables Assumed To Be Saved, Next: Unwanted Variables, Prev: Variables Assumed To Be Zero, Up: Working Programs Variables Assumed To Be Saved ----------------------------- Many Fortran programs were developed on systems that saved the values of all, or some, variables and arrays across procedure calls. As a result, many of these programs depend, sometimes inadvertently, on being able to assign a value to a variable, perform a `RETURN' to a calling procedure, and, upon subsequent invocation, reference the previously assigned variable to obtain the value. They expect this despite not using the `SAVE' statement to specify that the value in a variable is expected to survive procedure returns and calls. Depending on variables and arrays to retain values across procedure calls without using `SAVE' to require it violates the Fortran standards. You can ask `g77' to assume `SAVE' is specified for all relevant (local) variables and arrays by using the `-fno-automatic' option. Note that a program that works better when compiled with the `-fno-automatic' option is almost certainly depending on not having to use the `SAVE' statement as required by the Fortran standard. It might be worthwhile finding such cases and fixing them, using techniques such as compiling with the `-O -Wuninitialized' options using `g77'.  File: g77.info, Node: Unwanted Variables, Next: Unused Arguments, Prev: Variables Assumed To Be Saved, Up: Working Programs Unwanted Variables ------------------ The `-Wunused' option can find bugs involving implicit typing, sometimes more easily than using `-Wimplicit' in code that makes heavy use of implicit typing. An unused variable or array might indicate that the spelling for its declaration is different from that of its intended uses. Other than cases involving typos, unused variables rarely indicate actual bugs in a program. However, investigating such cases thoroughly has, on occasion, led to the discovery of code that had not been completely written--where the programmer wrote declarations as needed for the whole algorithm, wrote some or even most of the code for that algorithm, then got distracted and forgot that the job was not complete.  File: g77.info, Node: Unused Arguments, Next: Surprising Interpretations of Code, Prev: Unwanted Variables, Up: Working Programs Unused Arguments ---------------- As with unused variables, It is possible that unused arguments to a procedure might indicate a bug. Compile with `-W -Wunused' option to catch cases of unused arguments. Note that `-W' also enables warnings regarding overflow of floating-point constants under certain circumstances.  File: g77.info, Node: Surprising Interpretations of Code, Next: Aliasing Assumed To Work, Prev: Unused Arguments, Up: Working Programs Surprising Interpretations of Code ---------------------------------- The `-Wsuprising' option can help find bugs involving expression evaluation or in the way `DO' loops with non-integral iteration variables are handled. Cases found by this option might indicate a difference of interpretation between the author of the code involved, and a standard-conforming compiler such as `g77'. Such a difference might produce actual bugs. In any case, changing the code to explicitly do what the programmer might have expected it to do, so `g77' and other compilers are more likely to follow the programmer's expectations, might be worthwhile, especially if such changes make the program work better.  File: g77.info, Node: Aliasing Assumed To Work, Next: Output Assumed To Flush, Prev: Surprising Interpretations of Code, Up: Working Programs Aliasing Assumed To Work ------------------------ The `-falias-check', `-fargument-alias', `-fargument-noalias', and `-fno-argument-noalias-global' options, introduced in version 0.5.20 and `g77''s version 2.7.2.2.f.2 of `gcc', control the assumptions regarding aliasing (overlapping) of writes and reads to main memory (core) made by the `gcc' back end. They are effective only when compiling with `-O' (specifying any level other than `-O0') or with `-falias-check'. The default for Fortran code is `-fargument-noalias-global'. (The default for C code and code written in other C-based languages is `-fargument-alias'. These defaults apply regardless of whether you use `g77' or `gcc' to compile your code.) Note that, on some systems, compiling with `-fforce-addr' in effect can produce more optimal code when the default aliasing options are in effect (and when optimization is enabled). If your program is not working when compiled with optimization, it is possible it is violating the Fortran standards (77 and 90) by relying on the ability to "safely" modify variables and arrays that are aliased, via procedure calls, to other variables and arrays, without using `EQUIVALENCE' to explicitly set up this kind of aliasing. (The FORTRAN 77 standard's prohibition of this sort of overlap, generally referred to therein as "storage assocation", appears in Sections 15.9.3.6. This prohibition allows implementations, such as `g77', to, for example, implement the passing of procedures and even values in `COMMON' via copy operations into local, perhaps more efficiently accessed temporaries at entry to a procedure, and, where appropriate, via copy operations back out to their original locations in memory at exit from that procedure, without having to take into consideration the order in which the local copies are updated by the code, among other things.) To test this hypothesis, try compiling your program with the `-fargument-alias' option, which causes the compiler to revert to assumptions essentially the same as made by versions of `g77' prior to 0.5.20. If the program works using this option, that strongly suggests that the bug is in your program. Finding and fixing the bug(s) should result in a program that is more standard-conforming and that can be compiled by `g77' in a way that results in a faster executable. (You might want to try compiling with `-fargument-noalias', a kind of half-way point, to see if the problem is limited to aliasing between dummy arguments and `COMMON' variables--this option assumes that such aliasing is not done, while still allowing aliasing among dummy arguments.) An example of aliasing that is invalid according to the standards is shown in the following program, which might *not* produce the expected results when executed: I = 1 CALL FOO(I, I) PRINT *, I END SUBROUTINE FOO(J, K) J = J + K K = J * K PRINT *, J, K END The above program attempts to use the temporary aliasing of the `J' and `K' arguments in `FOO' to effect a pathological behavior--the simultaneous changing of the values of *both* `J' and `K' when either one of them is written. The programmer likely expects the program to print these values: 2 4 4 However, since the program is not standard-conforming, an implementation's behavior when running it is undefined, because subroutine `FOO' modifies at least one of the arguments, and they are aliased with each other. (Even if one of the assignment statements was deleted, the program would still violate these rules. This kind of on-the-fly aliasing is permitted by the standard only when none of the aliased items are defined, or written, while the aliasing is in effect.) As a practical example, an optimizing compiler might schedule the `J =' part of the second line of `FOO' *after* the reading of `J' and `K' for the `J * K' expression, resulting in the following output: 2 2 2 Essentially, compilers are promised (by the standard and, therefore, by programmers who write code they claim to be standard-conforming) that if they cannot detect aliasing via static analysis of a single program unit's `EQUIVALENCE' and `COMMON' statements, no such aliasing exists. In such cases, compilers are free to assume that an assignment to one variable will not change the value of another variable, allowing it to avoid generating code to re-read the value of the other variable, to re-schedule reads and writes, and so on, to produce a faster executable. The same promise holds true for arrays (as seen by the called procedure)--an element of one dummy array cannot be aliased with, or overlap, any element of another dummy array or be in a `COMMON' area known to the procedure. (These restrictions apply only when the procedure defines, or writes to, one of the aliased variables or arrays.) Unfortunately, there is no way to find *all* possible cases of violations of the prohibitions against aliasing in Fortran code. Static analysis is certainly imperfect, as is run-time analysis, since neither can catch all violations. (Static analysis can catch all likely violations, and some that might never actually happen, while run-time analysis can catch only those violations that actually happen during a particular run. Neither approach can cope with programs mixing Fortran code with routines written in other languages, however.) Currently, `g77' provides neither static nor run-time facilities to detect any cases of this problem, although other products might. Run-time facilities are more likely to be offered by future versions of `g77', though patches improving `g77' so that it provides either form of detection are welcome.  File: g77.info, Node: Output Assumed To Flush, Next: Large File Unit Numbers, Prev: Aliasing Assumed To Work, Up: Working Programs Output Assumed To Flush ----------------------- For several versions prior to 0.5.20, `g77' configured its version of the `libf2c' run-time library so that one of its configuration macros, `ALWAYS_FLUSH', was defined. This was done as a result of a belief that many programs expected output to be flushed to the operating system (under UNIX, via the `fflush()' library call) with the result that errors, such as disk full, would be immediately flagged via the relevant `ERR=' and `IOSTAT=' mechanism. Because of the adverse effects this approach had on the performance of many programs, `g77' no longer configures `libf2c' to always flush output. If your program depends on this behavior, either insert the appropriate `CALL FLUSH' statements, or modify the sources to the `libf2c', rebuild and reinstall `g77', and relink your programs with the modified library. (Ideally, `libf2c' would offer the choice at run-time, so that a compile-time option to `g77' or `f2c' could result in generating the appropriate calls to flushing or non-flushing library routines.) *Note Always Flush Output::, for information on how to modify the `g77' source tree so that a version of `libf2c' can be built and installed with the `ALWAYS_FLUSH' macro defined.  File: g77.info, Node: Large File Unit Numbers, Prev: Output Assumed To Flush, Up: Working Programs Large File Unit Numbers ----------------------- If your program crashes at run time with a message including the text `illegal unit number', that probably is a message from the run-time library, `libf2c', used, and distributed with, `g77'. The message means that your program has attempted to use a file unit number that is out of the range accepted by `libf2c'. Normally, this range is 0 through 99, and the high end of the range is controlled by a `libf2c' source-file macro named `MXUNIT'. If you can easily change your program to use unit numbers in the range 0 through 99, you should do so. Otherwise, see *Note Larger File Unit Numbers::, for information on how to change `MXUNIT' in `libf2c' so you can build and install a new version of `libf2c' that supports the larger unit numbers you need. *Note:* While `libf2c' places a limit on the range of Fortran file-unit numbers, the underlying library and operating system might impose different kinds of limits. For example, some systems limit the number of files simultaneously open by a running program. Information on how to increase these limits should be found in your system's documentation.  File: g77.info, Node: Overly Convenient Options, Next: Faster Programs, Prev: Working Programs, Up: Collected Fortran Wisdom Overly Convenient Command-line Options ====================================== These options should be used only as a quick-and-dirty way to determine how well your program will run under different compilation models without having to change the source. Some are more problematic than others, depending on how portable and maintainable you want the program to be (and, of course, whether you are allowed to change it at all is crucial). You should not continue to use these command-line options to compile a given program, but rather should make changes to the source code: `-finit-local-zero' (This option specifies that any uninitialized local variables and arrays have default initialization to binary zeros.) Many other compilers do this automatically, which means lots of Fortran code developed with those compilers depends on it. It is safer (and probably would produce a faster program) to find the variables and arrays that need such initialization and provide it explicitly via `DATA', so that `-finit-local-zero' is not needed. Consider using `-Wuninitialized' (which requires `-O') to find likely candidates, but do not specify `-finit-local-zero' or `-fno-automatic', or this technique won't work. `-fno-automatic' (This option specifies that all local variables and arrays are to be treated as if they were named in `SAVE' statements.) Many other compilers do this automatically, which means lots of Fortran code developed with those compilers depends on it. The effect of this is that all non-automatic variables and arrays are made static, that is, not placed on the stack or in heap storage. This might cause a buggy program to appear to work better. If so, rather than relying on this command-line option (and hoping all compilers provide the equivalent one), add `SAVE' statements to some or all program unit sources, as appropriate. Consider using `-Wuninitialized' (which requires `-O') to find likely candidates, but do not specify `-finit-local-zero' or `-fno-automatic', or this technique won't work. The default is `-fautomatic', which tells `g77' to try and put variables and arrays on the stack (or in fast registers) where possible and reasonable. This tends to make programs faster. *Note:* Automatic variables and arrays are not affected by this option. These are variables and arrays that are *necessarily* automatic, either due to explicit statements, or due to the way they are declared. Examples include local variables and arrays not given the `SAVE' attribute in procedures declared `RECURSIVE', and local arrays declared with non-constant bounds (automatic arrays). Currently, `g77' supports only automatic arrays, not `RECURSIVE' procedures or other means of explicitly specifying that variables or arrays are automatic. `-fugly' Fix the source code so that `-fno-ugly' 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, among the various "ugly" features. `-fGROUP-intrinsics-hide' Change the source code to use `EXTERNAL' for any external procedure that might be the name of an intrinsic. It is easy to find these using `-fGROUP-intrinsics-disable'.  File: g77.info, Node: Faster Programs, Prev: Overly Convenient Options, Up: Collected Fortran Wisdom Faster Programs =============== Aside from the usual `gcc' options, such as `-O', `-ffast-math', and so on, consider trying some of the following approaches to speed up your program (once you get it working). * Menu: * Aligned Data:: * Prefer Automatic Uninitialized Variables:: * Avoid f2c Compatibility:: * Use Submodel Options::  File: g77.info, Node: Aligned Data, Next: Prefer Automatic Uninitialized Variables, Up: Faster Programs Aligned Data ------------ On some systems, such as those with Pentium Pro CPUs, programs that make heavy use of `REAL(KIND=2)' (`DOUBLE PRECISION') might run much slower than possible due to the compiler not aligning these 64-bit values to 64-bit boundaries in memory. (The effect also is present, though to a lesser extent, on the 586 (Pentium) architecture.) The Intel x86 architecture generally ensures that these programs will work on all its implementations, but particular implementations (such as Pentium Pro) perform better with more strict alignment. (Such behavior isn't unique to the Intel x86 architecture.) Other architectures might *demand* 64-bit alignment of 64-bit data. There are a variety of approaches to use to address this problem: * Order your `COMMON' and `EQUIVALENCE' areas such that the variables and arrays with the widest alignment guidelines come first. For example, on most systems, this would mean placing `COMPLEX(KIND=2)', `REAL(KIND=2)', and `INTEGER(KIND=2)' entities first, followed by `REAL(KIND=1)', `INTEGER(KIND=1)', and `LOGICAL(KIND=1)' entities, then `INTEGER(KIND=6)' entities, and finally `CHARACTER' and `INTEGER(KIND=3)' entities. The reason to use such placement is it makes it more likely that your data will be aligned properly, without requiring you to do detailed analysis of each aggregate (`COMMON' and `EQUIVALENCE') area. Specifically, on systems where the above guidelines are appropriate, placing `CHARACTER' entities before `REAL(KIND=2)' entities can work just as well, but only if the number of bytes occupied by the `CHARACTER' entities is divisible by the recommended alignment for `REAL(KIND=2)'. By ordering the placement of entities in aggregate areas according to the simple guidelines above, you avoid having to carefully count the number of bytes occupied by each entity to determine whether the actual alignment of each subsequent entity meets the alignment guidelines for the type of that entity. If you don't ensure correct alignment of `COMMON' elements, the compiler may be forced by some systems to violate the Fortran semantics by adding padding to get `DOUBLE PRECISION' data properly aligned. If the unfortunate practice is employed of overlaying different types of data in the `COMMON' block, the different variants of this block may become misaligned with respect to each other. Even if your platform doesn't require strict alignment, `COMMON' should be laid out as above for portability. (Unfortunately the FORTRAN 77 standard didn't anticipate this possible requirement, which is compiler-independent on a given platform.) * Use the (x86-specific) `-malign-double' option when compiling programs for the Pentium and Pentium Pro architectures (called 586 and 686 in the `gcc' configuration subsystem). The warning about this in the `gcc' manual isn't generally relevant to Fortran, but using it will force `COMMON' to be padded if necessary to align `DOUBLE PRECISION' data. * Ensure that `crt0.o' or `crt1.o' on your system guarantees a 64-bit aligned stack for `main()'. The recent one from GNU (`glibc2') will do this on x86 systems, but we don't know of any other x86 setups where it will be right. Read your system's documentation to determine if it is appropriate to upgrade to a more recent version to obtain the optimal alignment. Progress is being made on making this work "out of the box" on future versions of `g77', `gcc', and some of the relevant operating systems (such as GNU/Linux).  File: g77.info, Node: Prefer Automatic Uninitialized Variables, Next: Avoid f2c Compatibility, Prev: Aligned Data, Up: Faster Programs Prefer Automatic Uninitialized Variables ---------------------------------------- If you're using `-fno-automatic' already, you probably should change your code to allow compilation with `-fautomatic' (the default), to allow the program to run faster. Similarly, you should be able to use `-fno-init-local-zero' (the default) instead of `-finit-local-zero'. This is because it is rare that every variable affected by these options in a given program actually needs to be so affected. For example, `-fno-automatic', which effectively `SAVE's every local non-automatic variable and array, affects even things like `DO' iteration variables, which rarely need to be `SAVE'd, and this often reduces run-time performances. Similarly, `-fno-init-local-zero' forces such variables to be initialized to zero--when `SAVE'd (such as when `-fno-automatic'), this by itself generally affects only startup time for a program, but when not `SAVE'd, it can slow down the procedure every time it is called. *Note Overly Convenient Command-Line Options: Overly Convenient 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.  File: g77.info, Node: Avoid f2c Compatibility, Next: Use Submodel Options, Prev: Prefer Automatic Uninitialized Variables, Up: Faster Programs Avoid f2c Compatibility ----------------------- If you aren't linking with any code compiled using `f2c', try using the `-fno-f2c' option when compiling *all* the code in your program. (Note that `libf2c' is *not* an example of code that is compiled using `f2c'--it is compiled by a C compiler, typically `gcc'.)  File: g77.info, Node: Use Submodel Options, Prev: Avoid f2c Compatibility, Up: Faster Programs Use Submodel Options -------------------- Using an appropriate `-m' option to generate specific code for your CPU may be worthwhile, though it may mean the executable won't run on other versions of the CPU that don't support the same instruction set. *Note Hardware Models and Configurations: (gcc)Submodel Options. For recent CPUs that don't have explicit support in the released version of `gcc', it may still be possible to get improvements. For instance, the flags recommended for 586/686 (Pentium(Pro)) chips for building the Linux kernel are: -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fomit-frame-pointer `-fomit-frame-pointer' will, however, inhibit debugging on x86 systems.  File: g77.info, Node: Trouble, Next: Open Questions, Prev: Collected Fortran Wisdom, Up: Top Known Causes of Trouble with GNU Fortran **************************************** This section describes known problems that affect users of GNU Fortran. Most of these are not GNU Fortran bugs per se--if they were, we would fix them. But the result for a user might be like the result of a bug. Some of these problems are due to bugs in other software, some are missing features that are too much work to add, and some are places where people's opinions differ as to what is best. Information on bugs that show up when configuring, porting, building, or installing `g77' is not provided here. *Note Problems Installing::. To find out about major bugs discovered in the current release and possible workarounds for them, retrieve `ftp://alpha.gnu.org/g77.plan'. (Note that some of this portion of the manual is lifted directly from the `gcc' manual, with minor modifications to tailor it to users of `g77'. Anytime a bug seems to have more to do with the `gcc' portion of `g77', *Note Known Causes of Trouble with GNU CC: (gcc)Trouble.) * Menu: * But-bugs:: Bugs really in other programs or elsewhere. * Actual Bugs:: Bugs and misfeatures we will fix later. * Missing Features:: Features we already know we want to add later. * Disappointments:: Regrettable things we can't change. * Non-bugs:: Things we think are right, but some others disagree. * Warnings and Errors:: Which problems in your code get warnings, and which get errors.  File: g77.info, Node: But-bugs, Next: Actual Bugs, Up: Trouble Bugs Not In GNU Fortran ======================= These are bugs to which the maintainers often have to reply, "but that isn't a bug in `g77'...". Some of these already are fixed in new versions of other software; some still need to be fixed; some are problems with how `g77' is installed or is being used; some are the result of bad hardware that causes software to misbehave in sometimes bizarre ways; some just cannot be addressed at this time until more is known about the problem. Please don't re-report these bugs to the `g77' maintainers--if you must remind someone how important it is to you that the problem be fixed, talk to the people responsible for the other products identified below, but preferably only after you've tried the latest versions of those products. The `g77' maintainers have their hands full working on just fixing and improving `g77', without serving as a clearinghouse for all bugs that happen to affect `g77' users. *Note Collected Fortran Wisdom::, for information on behavior of Fortran programs, and the programs that compile them, that might be *thought* to indicate bugs. * Menu: * Signal 11 and Friends:: Strange behavior by any software. * Cannot Link Fortran Programs:: Unresolved references. * Large Common Blocks:: Problems on older GNU/Linux systems. * Debugger Problems:: When the debugger crashes. * NeXTStep Problems:: Misbehaving executables. * Stack Overflow:: More misbehaving executables. * Nothing Happens:: Less behaving executables. * Strange Behavior at Run Time:: Executables misbehaving due to bugs in your program. * Floating-point Errors:: The results look wrong, but....