GFORTRAN(1)

๐Ÿ“ฆ
version 14-20240412 ยท 5 versions
, in ubuntu noble

๐ŸŽ€ gfortran(1) ยท GNU manual ๐ŸŽ€

โœจ NAME โœจ

okay bestie, the NAME section is literally just gfortran - GNU Fortran compiler ๐Ÿ’– that's the whole tea, it's the Fortran compiler from GNU, and it's iconic. ๐Ÿ’…

โœจ SYNOPSIS โœจ

Here's the lineup of how you call it. Ignore the vibes for a sec and just look at the shape of the command ๐Ÿ‘€

gfortran [-c|-S|-E]
         [-g] [-pg] [-Olevel]
         [-Wwarn...] [-pedantic]
         [-Idir...] [-Ldir...]
         [-Dmacro[=defn]...] [-Umacro]
         [-foption...]
         [-mmachine-option...]
         [-o outfile] infile...

Heads up, this only shows the most useful options up top. The rest are waiting for you further down, so keep scrolling ๐Ÿฆ‹

โœจ DESCRIPTION โœจ

So the gfortran command takes every option that gcc takes, no cap. ๐Ÿ”ฅ This page only covers the stuff that's specific to GNU Fortran, because the rest is already documented elsewhere ๐Ÿงš

Here's the lowkey best part: every GCC and GNU Fortran option works with both gfortran and gcc. That includes other drivers built at the same time, like g++. Adding GNU Fortran to the GCC distribution means all the relevant drivers accept Fortran options, and that's just iconic behaviour ๐Ÿ‘‘

Some options come in a positive form and a negative form. For example, the negative version of -ffoo is -fno-foo. This manual only documents whichever of the two is not the default, so if you're looking for the other one, you're gonna have to flip it yourself ๐Ÿ™ˆ

โœจ OPTIONS โœจ

Here's the cheat sheet for every option that belongs to GNU Fortran, sorted into groups. The explanations come after this, so don't panic ๐Ÿ’–

๐Ÿ’œ Fortran Language Options ๐Ÿ’œ

-fall-intrinsics -fallow-argument-mismatch -fallow-invalid-boz
-fbackslash -fcray-pointer -fd-lines-as-code -fd-lines-as-comments
-fdec -fdec-char-conversions -fdec-structure -fdec-intrinsic-ints
-fdec-static -fdec-math -fdec-include -fdec-format-defaults
-fdec-blank-format-item -fdefault-double-8 -fdefault-integer-8
-fdefault-real-8 -fdefault-real-10 -fdefault-real-16 -fdollar-ok
-ffixed-line-length-n -ffixed-line-length-none -fpad-source
-ffree-form -ffree-line-length-n -ffree-line-length-none
-fimplicit-none -finteger-4-integer-8 -fmax-identifier-length
-fmodule-private -ffixed-form -fno-range-check -fopenacc -fopenmp
-fopenmp-allocators -fopenmp-simd -freal-4-real-10 -freal-4-real-16
-freal-4-real-8 -freal-8-real-10 -freal-8-real-16 -freal-8-real-4
-std=std -ftest-forall-temp

๐ŸŒธ Preprocessing Options ๐ŸŒธ

-A-question[=answer] -Aquestion=answer -C -CC -Dmacro[=defn] -H -P
-Umacro -cpp -dD -dI -dM -dN -dU -fworking-directory -imultilib dir
-iprefix file -iquote -isysroot dir -isystem dir -nocpp -nostdinc
-undef

๐Ÿšจ Error and Warning Options ๐Ÿšจ

-Waliasing -Wall -Wampersand -Warray-bounds -Wc-binding-type
-Wcharacter-truncation -Wconversion -Wdo-subscript
-Wfunction-elimination -Wimplicit-interface -Wimplicit-procedure
-Wintrinsic-shadow -Wuse-without-only -Wintrinsics-std
-Wline-truncation -Wno-align-commons -Wno-overwrite-recursive
-Wno-tabs -Wreal-q-constant -Wsurprising -Wunderflow
-Wunused-parameter -Wrealloc-lhs -Wrealloc-lhs-all
-Wfrontend-loop-interchange -Wtarget-lifetime -fmax-errors=n
-fsyntax-only -pedantic -pedantic-errors

๐Ÿ” Debugging Options ๐Ÿ”

-fbacktrace -fdebug-aux-vars -ffpe-trap=list -ffpe-summary=list

๐Ÿ“ Directory Options ๐Ÿ“

-Idir  -Jdir -fintrinsic-modules-path dir
-static-libgfortran  -static-libquadmath

โฑ๏ธ Runtime Options โฑ๏ธ

-fconvert=conversion -fmax-subrecord-length=length
-frecord-marker=length -fsign-zero

๐Ÿค Interoperability Options ๐Ÿค

-fc-prototypes -fc-prototypes-external

๐Ÿ› ๏ธ Code Generation Options ๐Ÿ› ๏ธ

-faggressive-function-elimination -fblas-matmul-limit=n
-fbounds-check -ftail-call-workaround -ftail-call-workaround=n
-fcheck-array-temporaries
-fcheck=<all|array-temps|bits|bounds|do|mem|pointer|recursion>
-fcoarray=<none|single|lib> -fexternal-blas -ff2c
-ffrontend-loop-interchange -ffrontend-optimize -finit-character=n
-finit-integer=n -finit-local-zero -finit-derived
-finit-logical=<true|false> -finit-real=<zero|inf|-inf|nan|snan>
-finline-matmul-limit=n -finline-arg-packing
-fmax-array-constructor=n -fmax-stack-var-size=n -fno-align-commons
-fno-automatic -fno-protect-parens -fno-underscoring
-fsecond-underscore -fpack-derived -frealloc-lhs -frecursive
-frepack-arrays -fshort-enums -fstack-arrays

๐Ÿงช Developer Options ๐Ÿงช

-fdump-fortran-global -fdump-fortran-optimized
-fdump-fortran-original -fdump-parse-tree -save-temps

๐Ÿ’… Options controlling Fortran dialect ๐Ÿ’…

The options below control the finer details of which Fortran dialect the compiler accepts. Let's go through them one by one, bestie ๐Ÿซถ

  • -ffree-form, -ffixed-form โ€” These pick the layout of the source file. Free form showed up in Fortran 90, while fixed form was the classic move in older Fortran programs. If you don't specify either one, the file extension decides the source form for you ๐Ÿ“„
  • -fall-intrinsics โ€” This makes every intrinsic procedure get accepted, including the GNU-specific extensions. It's super useful together with -std= if you want to force standard compliance but still get the full set of gfortran intrinsics ๐Ÿ’– The catch is that -Wintrinsics-std gets ignored, and no user-defined procedure with the same name as an intrinsic will be called unless it's explicitly declared EXTERNAL.
  • -fallow-argument-mismatch โ€” Some code calls external procedures with mismatches, either between the call and the procedure definition or between different calls. That code isn't conforming and usually gets flagged as an error. This option downgrades that error to a warning, and the only way to turn that warning off is to disable all warnings with -w. Only one occurrence per argument gets flagged. This option is implied by -std=legacy.
Using this option is strongly discouraged, no cap ๐Ÿ™…โ€โ™€๏ธ You can write standard-conforming code that accepts different argument types by using an explicit interface and TYPE(*), so that's the better route.
  • -fallow-invalid-boz โ€” A BOZ literal constant can only show up in a few specific spots in standard Fortran. This option turns the error into a warning and lets a BOZ literal sneak into places where the standard would normally ban it ๐Ÿ™ˆ
  • -fd-lines-as-code, -fd-lines-as-comments โ€” These give lines starting with d or D in fixed form sources some special treatment. With -fd-lines-as-code, they get treated as if the first column held a blank. With -fd-lines-as-comments, they're treated as comment lines ๐Ÿฆ‹
  • -fdec โ€” This turns on DEC compatibility mode, which enables extensions that mimic how older compilers (like DEC's) behaved by default. Heads up, these features are non-standard, so avoid them at all costs ๐Ÿ’€ For the full scoop on how GNU Fortran implements these extensions, check the full documentation.
These features are non-standard and should be avoided at all costs. Seriously, bestie ๐Ÿ’€

Turning this on also flips on these: -fdollar-ok -fcray-pointer -fdec-char-conversions -fdec-structure -fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include -fdec-blank-format-item -fdec-format-defaults. And if -fd-lines-as-code/-fd-lines-as-comments aren't set, then -fdec also sets -fd-lines-as-comments โœจ

  • -fdec-char-conversions โ€” This lets you use character literals in assignments and DATA statements for non-character variables ๐ŸŒˆ
  • -fdec-structure โ€” This enables DEC STRUCTURE and RECORD, plus UNION, MAP, and the dot (.) as a member separator (on top of %). It's only here for compatibility, though, so Fortran 90 derived types are the better move wherever you can use them ๐Ÿ’…
  • -fdec-intrinsic-ints โ€” This enables the B/I/J/K kind variants of the existing integer functions, like BIAND, IIAND, JIAND, and so on. For the complete list, check the full documentation ๐Ÿ”ข
  • -fdec-math โ€” This one is obsolete ๐Ÿฅ€ It used to enable legacy math intrinsics like COTAN and the degree-valued trig functions (TAND, ATAND, etc...) so older code would still work. It doesn't do anything anymore, since those trig functions are now either part of Fortran 2023 or GNU extensions.
  • -fdec-static โ€” This turns on DEC-style STATIC and AUTOMATIC attributes so you can explicitly say how variables and other objects are stored ๐Ÿ“ฆ
  • -fdec-include โ€” This lets INCLUDE get parsed as a statement, in addition to being parsed as an INCLUDE line. When it's parsed as a statement, the INCLUDE doesn't have to live on a single line and can use line continuations ๐Ÿงต
  • -fdec-format-defaults โ€” This lets the format specifiers F, G, and I get used without width specifiers, and default widths get used instead โœจ
  • -fdec-blank-format-item โ€” This enables a blank format item at the end of a format specification, which means there's nothing after the final comma ๐Ÿซง
  • -fdollar-ok โ€” This allows $ as a valid non-first character in a symbol name. Symbols that start with $ are still rejected, because it's unclear which implicit typing rules should apply, since different vendors do it differently. Using $ in IMPLICIT statements is also rejected ๐Ÿšซ
  • -fbackslash โ€” This changes how backslashes in string literals work, from a single backslash character to "C-style" escape characters. These combos get expanded: \a, \b, \f, \n, \r, \t, \v, \\, and \0, which become the ASCII alert, backspace, form feed, newline, carriage return, horizontal tab, vertical tab, backslash, and NUL characters, in that order. On top of that, \xnn, \unnnn, and \Unnnnnnnn (where each n is a hexadecimal digit) get translated into the Unicode characters for those code points ๐ŸŒ Any other combo of a character preceded by \ stays unexpanded.
  • -fmodule-private โ€” This sets the default accessibility of module entities to PRIVATE. Use-associated entities won't be accessible unless they're explicitly declared PUBLIC ๐Ÿ”’
  • -ffixed-line-length-n โ€” This sets the column after which characters get ignored in typical fixed-form lines of the source file. Unless you use -fno-pad-source, spaces are also assumed (as if the line were padded to that length) after the ends of short fixed-form lines ๐Ÿ“ Popular values for n are 72 (the standard and the default), 80 (card image), and 132 (which matches the "extended-source" options in some popular compilers). n can also be none, which means the entire line is meaningful and continued character constants never get implicit spaces appended to fill out the line. And -ffixed-line-length-0 does the exact same thing as -ffixed-line-length-none ๐ŸŽ€
  • -fno-pad-source: okay so by default, fixed-form lines get spaces assumed after the end of short ones, like they're padded out to the full length ๐Ÿ’… That padding doesn't happen if you use -ffixed-line-length-0, -ffixed-line-length-none, or -fno-pad-source. With any of those, continued character constants never get implicit spaces tacked on to fill out the line ๐ŸŽ€
  • -ffree-line-length-n: sets the column after which characters get ignored in typical free-form lines in the source file. The default is 132 ๐Ÿฆ‹ n can be none, which means the entire line counts โœจ -ffree-line-length-0 is the same thing as -ffree-line-length-none ๐ŸŒธ
  • -fmax-identifier-length=n: sets the max identifier length you're allowed to use. Typical values are 31 (Fortran 95) and 63 (Fortran 2003 and later) ๐Ÿ’œ
  • -fimplicit-none: no implicit typing allowed, unless you override it with explicit IMPLICIT statements. It's basically the same as adding implicit none to the start of every procedure ๐Ÿ™ˆ
  • -fcray-pointer: turns on the Cray pointer extension, which gives you C-like pointer functionality ๐Ÿงš
  • -fopenacc: turns on handling of OpenACC directives !$acc in free-form Fortran, and !$acc, c$acc and *$acc in fixed-form Fortran ๐Ÿ”ฅ With this flag, the compiler generates accelerated code according to the OpenACC Application Programming Interface v2.6 (https://www.openacc.org). It implies -pthread, so it's only supported on targets that have support for -pthread. It also implies -frecursive ๐Ÿ‘‘
  • -fopenmp: turns on handling of OpenMP directives !$omp in Fortran. It also enables the conditional compilation sentinel !$ in Fortran. In fixed source form Fortran, the sentinels can also start with c or *. With -fopenmp, the compiler generates parallel code according to the OpenMP Application Program Interface v4.5 (https://www.openmp.org). It implies -pthread, so it's only supported on targets that have support for -pthread. -fopenmp also implies -fopenmp-simd and -frecursive โœจ
  • -fopenmp-allocators: turns on handling of allocation, reallocation and deallocation of Fortran allocatable and pointer variables that are allocated using the !$omp allocators and !$omp allocate constructs. Files containing either directive have to be compiled with this option in addition to -fopenmp. Also, every file that might deallocate or reallocate a variable allocated with an OpenMP allocator has to be compiled with this option too ๐Ÿ˜ญ That includes intrinsic assignment to allocatable variables when reallocation may occur, and deallocation due to any of these: end of scope, explicit deallocation, intent(out), deallocation of allocatable components, etc. Files that don't change the allocation status, or only touch components of a derived type that weren't allocated using those two directives, don't need this option. Same goes for files that handle such variables after they've been deallocated or allocated by the normal Fortran allocator ๐ŸŒˆ
  • -fopenmp-simd: turns on handling of OpenMP's "simd", "declare simd", "declare reduction", "assume", "ordered", "scan" and "loop" directives, plus combined or composite directives with "simd" as a constituent, written with !$omp in Fortran ๐Ÿ’… It also enables the conditional compilation sentinel !$ in Fortran. In fixed source form Fortran, the sentinels can also start with c or *. Other OpenMP directives get ignored. Unless -fopenmp is also specified, the "loop" region binds to the current task region, no matter what "bind" clause you wrote ๐Ÿซถ
  • -fno-range-check: disables range checking on the results of simplifying constant expressions during compilation. For example, GNU Fortran gives a compile-time error when simplifying "a = 1. / 0". With this option, no error shows up and "a" gets the value "+Infinity" ๐Ÿฆ‹ If an expression evaluates to a value outside the relevant range of ["-HUGE()":HUGE()], the expression gets replaced by "-Inf" or "+Inf", whichever fits. Similarly, DATA i/Z'FFFFFFFF'/ causes an integer overflow on most systems, but with -fno-range-check the value "wraps around" and i gets initialized to -1 instead ๐Ÿ’€
  • -fdefault-integer-8: sets the default integer and logical types to an 8 byte wide type ๐Ÿ’– This also changes the kind of integer constants like 42. Unlike -finteger-4-integer-8, it does not promote variables with an explicit kind declaration.
  • -fdefault-real-8: sets the default real type to an 8 byte wide type. This also changes the kind of non-double real constants like 1.0. The default width of DOUBLE PRECISION and double real constants like 1.d0 gets promoted to 16 bytes if possible ๐Ÿ”ฅ If -fdefault-double-8 is given along with fdefault-real-8, then DOUBLE PRECISION and double real constants are not promoted. Unlike -freal-4-real-8, fdefault-real-8 does not promote variables with explicit kind declarations ๐ŸŒธ
  • -fdefault-real-10: sets the default real type to a 10 byte wide type. This also changes the kind of non-double real constants like 1.0. The default width of DOUBLE PRECISION and double real constants like 1.d0 gets promoted to 16 bytes if possible ๐ŸŒˆ If -fdefault-double-8 is given along with fdefault-real-10, then DOUBLE PRECISION and double real constants are not promoted. Unlike -freal-4-real-10, fdefault-real-10 does not promote variables with explicit kind declarations โœจ
  • -fdefault-real-16: sets the default real type to a 16 byte wide type. This also changes the kind of non-double real constants like 1.0. The default width of DOUBLE PRECISION and double real constants like 1.d0 gets promoted to 16 bytes if possible ๐Ÿ’œ If -fdefault-double-8 is given along with fdefault-real-16, then DOUBLE PRECISION and double real constants are not promoted. Unlike -freal-4-real-16, fdefault-real-16 does not promote variables with explicit kind declarations ๐Ÿซถ
  • -fdefault-double-8: sets the DOUBLE PRECISION type and double real constants like 1.d0 to an 8 byte wide type. If that's already the default, it does nothing ๐Ÿ™ˆ This option stops -fdefault-real-8, -fdefault-real-10, and -fdefault-real-16 from promoting DOUBLE PRECISION and double real constants like 1.d0 to 16 bytes ๐Ÿงš
  • -finteger-4-integer-8: promotes all INTEGER(KIND=4) entities to INTEGER(KIND=8) entities. If KIND=8 is unavailable, an error gets issued.
โš ๏ธ This option should be used with care, and it may not be suitable for your codes. Areas of possible concern include calls to external procedures, alignment in EQUIVALENCE and/or COMMON, generic interfaces, BOZ literal constant conversion, and I/O. It's suggested that you inspect the intermediate representation of the translated Fortran code, produced by -fdump-tree-original.
  • -freal-4-real-8, -freal-4-real-10, -freal-4-real-16, -freal-8-real-4, -freal-8-real-10, -freal-8-real-16: promote all REAL(KIND=M) entities to REAL(KIND=N) entities. If REAL(KIND=N) is unavailable, an error gets issued ๐Ÿ˜ญ The -freal-4- flags also affect the default real kind, and the -freal-8- flags also affect the double-precision real kind. All other real-kind types are unaffected by this option. The promotion also applies to real literal constants of default and double-precision kind, with a specified kind number of 4 or 8 respectively. However, -fdefault-real-8, -fdefault-real-10, -fdefault-real-10, and -fdefault-double-8 take precedence for the default and double-precision real kinds, both for real literal constants and for declarations without a kind number. Note that for REAL(KIND=KIND(1.0)) the literal may get promoted, and then the result may get promoted again ๐Ÿ‘‘
โš ๏ธ These options should be used with care, and they may not be suitable for your codes. Areas of possible concern include calls to external procedures, alignment in EQUIVALENCE and/or COMMON, generic interfaces, BOZ literal constant conversion, I/O, and calls to intrinsic procedures when passing a value to the kind= dummy argument. It's suggested that you inspect the intermediate representation of the translated Fortran code, produced by -fdump-fortran-original or -fdump-tree-original.
  • -std=std: specifies the standard the program is expected to conform to, which may be one of f95, f2003, f2008, f2018, f2023, gnu, or legacy ๐Ÿ’… The default for std is gnu, which is a superset of the latest Fortran standard that includes all the extensions GNU Fortran supports, though warnings get shown for obsolete extensions not recommended for new code. The legacy value is equivalent but without the warnings for obsolete extensions, and it may be useful for old non-standard programs ๐Ÿฆ‹ The f95, f2003, f2008, f2018, and f2023 values specify strict conformance to the Fortran 95, Fortran 2003, Fortran 2008, Fortran 2018 and Fortran 2023 standards, respectively. Errors get given for all extensions beyond the relevant language standard, and warnings get given for Fortran 77 features that are permitted but obsolescent in later standards. The deprecated option -std=f2008ts acts as an alias for -std=f2018.
๐Ÿšซ -std=f2008ts is only there for backwards compatibility with earlier gfortran versions, and you should not use it anymore.
  • -ftest-forall-temp: enhances test coverage by forcing most forall assignments to use a temporary ๐Ÿงช

โœจ Enable and customize preprocessing โœจ

Many Fortran compilers, GNU Fortran included, let you pass source code through a C preprocessor (CPP; sometimes also called the Fortran preprocessor, FPP) so you can do conditional compilation ๐ŸŒˆ For GNU Fortran, this is the GNU C Preprocessor in traditional mode. On systems with case-preserving file names, the preprocessor gets invoked automatically if the filename extension is .F, .FOR, .FTN, .fpp, .FPP, .F90, .F95, .F03 or .F08 ๐Ÿ’– To manually invoke the preprocessor on any file, use -cpp. To disable preprocessing on files where the preprocessor runs automatically, use -nocpp ๐Ÿซถ

Okay so, if a preprocessed file pulls in another file with the Fortran INCLUDE statement, that included file does not get preprocessed ๐Ÿ™ˆ If you want included files preprocessed too, use the preprocessor version instead: #include ๐Ÿ’…

If GNU Fortran calls the preprocessor, __GFORTRAN__ gets defined โœจ You can check the compiler version with __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ ๐ŸŽ€ For the full details, see Top,,Overview,cpp,The C Preprocessor.

GNU Fortran also supports a bunch of extra INTEGER and REAL kind types on top of the ones the Fortran standard requires ๐ŸŒˆ Which ones you get depends on your architecture, so the preprocessor macros __GFC_INT_1__, __GFC_INT_2__, __GFC_INT_8__, __GFC_INT_16__, __GFC_REAL_10__ and __GFC_REAL_16__ let you conditionally include code for them ๐Ÿฆ‹

Now, CPP is the de facto standard for preprocessing Fortran, but Part 3 of the Fortran 95 standard (ISO/IEC 1539-3:1998) defines Conditional Compilation ๐Ÿงš It isn't widely used, and GNU Fortran doesn't directly support it ๐Ÿฅฒ If you need it, the program coco can preprocess those files. You'll find it at http://www.daniellnagle.com/coco.html ๐Ÿ”—

The following options control preprocessing of Fortran code ๐Ÿ’–

  • -cpp, -nocpp โ€” Turns preprocessing on โœจ The preprocessor runs automatically if your file extension is .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 or .F08. Use -cpp to manually turn it on for any kind of Fortran file. To turn it off for files with any of those extensions, use the negative form, -nocpp.

The preprocessor runs in traditional mode ๐Ÿ™ƒ Any file-format restrictions, especially the line length limits, apply to the preprocessed output too, so it might be a good idea to use -ffree-line-length-none or -ffixed-line-length-none.

  • -dM โ€” Instead of the normal output, you get a list of #define directives for every macro defined while the preprocessor runs, predefined ones included ๐Ÿ“œ It's a great way to see what's already predefined in your version of the preprocessor. If you don't have a file called foo.f90, this command will show all the predefined macros:
touch foo.f90; gfortran -cpp -E -dM foo.f90
  • -dD โ€” Same vibe as -dM, but with two differences ๐Ÿ’… It leaves out the predefined macros, and it outputs both the #define directives and the result of preprocessing. Both kinds of output go to the standard output file.
  • -dN โ€” Like -dD, but it only emits the macro names, not their expansions ๐Ÿซถ
  • -dU โ€” Like dD except only macros that get expanded, or whose definedness gets tested in preprocessor directives, are output ๐Ÿ‘€ The output is delayed until that macro is used or tested, and #undef directives are also output for macros that were tested but undefined at that point.
  • -dI โ€” Outputs #include directives on top of the preprocessing result ๐ŸŒธ
  • -fworking-directory โ€” Turns on linemarkers in the preprocessor output so the compiler knows the current working directory at the time of preprocessing ๐Ÿ—บ๏ธ With this on, the preprocessor emits a second linemarker after the initial one, containing the current working directory followed by two slashes. When that directory shows up in the preprocessed input, GCC uses it as the current working directory in some debugging information formats. This option is turned on automatically when debugging information is enabled, but you can block that with the negated form, -fno-working-directory. If the -P flag is in the command line, this option does nothing, since no #line directives get emitted whatsoever ๐Ÿ™…โ€โ™€๏ธ
  • -idirafter dir โ€” Searches dir for include files, but only after all the directories given with -I and the standard system directories have been exhausted ๐Ÿ˜ค dir gets treated as a system include directory. If dir begins with =, that = gets replaced by the sysroot prefix; see --sysroot and -isysroot.
  • -imultilib dir โ€” Uses dir as a subdirectory of the directory containing target-specific C++ headers ๐Ÿงฉ
  • -iprefix prefix โ€” Sets prefix as the prefix for later -iwithprefix options ๐Ÿ“‚ If the prefix is a directory, include the final /.
  • -isysroot dir โ€” Works like the --sysroot option, but only applies to header files ๐ŸŽ€ See the --sysroot option for more info.
  • -iquote dir โ€” Searches dir only for header files requested with #include "file". They don't get searched for #include <file> ๐Ÿ™…โ€โ™€๏ธ This happens before all the -I directories and before the standard system directories. If dir begins with =, that = gets replaced by the sysroot prefix; see --sysroot and -isysroot.
  • -isystem dir โ€” Searches dir for header files after all the -I directories but before the standard system directories ๐ŸŒท It gets marked as a system directory, so it gets the same special treatment as the standard system directories. If dir begins with =, that = gets replaced by the sysroot prefix; see --sysroot and -isysroot.
  • -nostdinc โ€” Doesn't search the standard system directories for header files ๐Ÿšซ Only the directories you gave with -I options (plus the directory of the current file, if that's relevant) get searched.
  • -undef โ€” Doesn't predefine any system-specific or GCC-specific macros ๐Ÿงผ The standard predefined macros stay defined.
  • -Apredicate=answer โ€” Makes an assertion with the predicate predicate and the answer answer ๐Ÿ’œ This form is preferred over the older -A predicate(answer) form, which is still supported, because it doesn't use shell special characters.
  • -A-predicate=answer โ€” Cancels an assertion with the predicate predicate and the answer answer ๐Ÿ™…โ€โ™€๏ธ
  • -C โ€” Keeps comments instead of discarding them ๐Ÿ’ฌ All comments pass through to the output file, except comments in processed directives, which get deleted along with the directive.

Be ready for side effects with -C ๐Ÿ‘€ It makes the preprocessor treat comments as tokens in their own right. For example, a comment at the start of what would be a directive line turns that line into an ordinary source line, since the first token on the line is no longer a #.

Warning: this currently handles C-style comments only. The preprocessor does not yet recognize Fortran-style comments ๐Ÿ’€
  • -CC โ€” Keeps comments, even during macro expansion ๐Ÿง  It's like -C, except comments inside macros also get passed through to the output file wherever the macro is expanded.

On top of the side effects of -C, -CC converts all C++-style comments inside a macro into C-style comments ๐Ÿ›ก๏ธ This stops a later use of that macro from accidentally commenting out the rest of the source line. The -CC option is generally used to support lint comments.

Warning: this currently handles C- and C++-style comments only. The preprocessor does not yet recognize Fortran-style comments ๐Ÿ’€
  • -Dname โ€” Predefines name as a macro, with the definition 1 ๐Ÿ“
  • -Dname=definition โ€” The contents of definition get tokenized and processed as if they appeared during translation phase three in a #define directive ๐Ÿงƒ In particular, the definition gets cut off at embedded newline characters.

If you call the preprocessor from a shell or shell-like program, you might need the shell's quoting syntax to protect characters like spaces that mean something in shell syntax ๐Ÿš

Want to define a function-like macro on the command line? Write its argument list in parentheses before the equals sign (if there is one) โœจ Parentheses mean something to most shells, so you'll need to quote the option. With sh and csh, -D'name(args...)=definition' works.

The -D and -U options get processed in the order you give them on the command line ๐Ÿ” All the -imacros file and -include file options get processed after all the -D and -U options.

  • -H โ€” Prints the name of each header file used, along with the other normal activities ๐Ÿฆ‹ Each name is indented to show how deep it sits in the #include stack.
  • -P โ€” Stops linemarkers from being generated in the preprocessor output ๐Ÿ™ˆ This might come in handy when you run the preprocessor on something that isn't C code and will be sent to a program that might get confused by the linemarkers.
  • -Uname โ€” Cancels any previous definition of name, whether it was built in or provided with a -D option ๐Ÿงน

โœจ Options to request or suppress errors and warnings โœจ

Errors are diagnostic messages saying GNU Fortran can't compile a particular piece of source code ๐Ÿ˜ญ The compiler keeps going anyway to report more errors and help you debug, but it won't produce any compiled output.

Warnings are diagnostic messages about constructions that aren't inherently wrong but are risky or suggest there's probably a bug in your program ๐Ÿ‘€ Unless -Werror is specified, warnings don't stop your program from compiling.

You can request lots of specific warnings with options that begin with -W. For example, -Wimplicit requests warnings about implicit declarations ๐Ÿ’… Each of these specific warning options also has a negative form beginning with -Wno- that turns the warnings off. For example, -Wno-implicit. This manual only lists one of the two forms, whichever one isn't the default ๐Ÿซถ

These options control how many errors and warnings GNU Fortran produces, and what kinds:

  • -fmax-errors=n โ€” Limits the number of error messages to n. When you hit that number, GNU Fortran bails out instead of trying to keep processing the source code ๐Ÿ›‘ If n is 0, there's no limit on how many error messages get produced.
  • -fsyntax-only โ€” Checks the code for syntax errors but doesn't actually compile it ๐Ÿ” This generates module files for each module in the code, but no other output file.
  • -Wpedantic, -pedantic โ€” Issues warnings for uses of extensions to Fortran ๐Ÿค“ -pedantic also applies to C-language constructs where they show up in GNU Fortran source files, such as using \e in a character constant inside a directive like #include.

Valid Fortran programs should compile totally fine with or without this option โœจ But without it, certain GNU extensions and traditional Fortran features are also supported ๐ŸŒˆ Turn this on and a lot of those get rejected ๐Ÿ™ˆ

Some people reach for -pedantic to check their code for conformance and then feel betrayed ๐Ÿ˜ญ It catches some nonstandard practices, but not all of them. Improvements to GNU Fortran in this area are super welcome ๐Ÿซถ

Use this together with -std=f95, -std=f2003, -std=f2008, -std=f2018 or -std=f2023 ๐Ÿ’–

  • -pedantic-errors โ€” same energy as -pedantic, except you get actual errors instead of warnings ๐Ÿ’€
  • -Wall โ€” turns on the commonly used warnings for stuff we recommend avoiding (and that we think is easy to avoid) โœจ Right now that's -Waliasing, -Wampersand, -Wconversion, -Wsurprising, -Wc-binding-type, -Wintrinsics-std, -Wtabs, -Wintrinsic-shadow, -Wline-truncation, -Wtarget-lifetime, -Winteger-division, -Wreal-q-constant, -Wunused and -Wundefined-do-loop ๐Ÿ‘‘
  • -Waliasing โ€” possible aliasing of dummy arguments ๐Ÿ‘€ It warns if the same actual argument gets linked to a dummy argument with INTENT(IN) and a dummy argument with INTENT(OUT) in a call with an explicit interface.

The following example will trigger the warning ๐Ÿšจ

interface
  subroutine bar(a,b)
    integer, intent(in) :: a
    integer, intent(out) :: b
  end subroutine
end interface
integer :: a

call bar(a,a)
  • -Wampersand โ€” flags a missing ampersand in continued character constants ๐ŸŽ€ The warning shows up with -Wampersand, -pedantic, -std=f95, -std=f2003, -std=f2008, -std=f2018 and -std=f2023. Note: if there's no ampersand in a continued character constant, GNU Fortran assumes the continuation happens at the first non-comment, non-whitespace character after the ampersand that started the continuation ๐Ÿค“
  • -Warray-temporaries โ€” warns about array temporaries the compiler makes on its own ๐Ÿงš This info is sometimes handy for optimization, so you can dodge those temporaries.
  • -Wc-binding-type โ€” warns if a variable might not be C interoperable ๐Ÿฆ‹ Specifically, it's the case when the variable is declared with an intrinsic type of default kind instead of a kind parameter meant for C interoperability from the intrinsic ISO_C_Binding module. This one is implied by -Wall.
  • -Wcharacter-truncation โ€” warns when a character assignment is going to truncate the assigned string โœ‚๏ธ
  • -Wline-truncation โ€” warns when a source code line is going to get truncated ๐Ÿ“ This is implied by -Wall. For free-form source code, the default is -Werror=line-truncation, so truncations get reported as errors ๐Ÿ’€
  • -Wconversion โ€” warns about implicit conversions that are likely to change the value of the expression after conversion ๐Ÿ”ฅ Implied by -Wall.
  • -Wconversion-extra โ€” warns about implicit conversions between different types and kinds ๐Ÿ’œ This one does not imply -Wconversion.
  • -Wextra โ€” enables some warning options for language features that can be problematic ๐ŸŒธ Right now that's -Wcompare-reals, -Wunused-parameter and -Wdo-subscript.
  • -Wfrontend-loop-interchange โ€” warns when -ffrontend-loop-interchange is used to do loop interchanges ๐Ÿ”„
  • -Wimplicit-interface โ€” warns if a procedure is called without an explicit interface ๐Ÿ™‹โ€โ™€๏ธ Heads up though: it only checks that an explicit interface is present. It doesn't check that the declared interfaces are consistent across program units.
  • -Wimplicit-procedure โ€” warns if a procedure is called that has neither an explicit interface nor has been declared as "EXTERNAL" ๐Ÿซ 
  • -Winteger-division โ€” warns if a constant integer division truncates its result ๐Ÿ• For example, 3/5 evaluates to 0.
  • -Wintrinsics-std โ€” warns if gfortran finds a procedure named like an intrinsic that isn't available in the currently selected standard (set with -std) ๐Ÿง Because of that, it gets treated as an "EXTERNAL" procedure instead. -fall-intrinsics can be used to never trigger this and always link to the intrinsic, no matter which standard you picked โœจ
  • -Wno-overwrite-recursive โ€” tells gfortran not to warn when -fno-automatic is used with -frecursive ๐Ÿ™…โ€โ™€๏ธ Recursion will be broken if the relevant local variables don't have the "AUTOMATIC" attribute explicitly declared. Use this to shush the warning when you know recursion isn't broken. Super useful for build environments that use -Werror.
  • -Wreal-q-constant โ€” makes a warning appear if a real-literal-constant contains a "q" exponent letter ๐Ÿ”ข
  • -Wsurprising โ€” warns when "suspicious" code constructs show up ๐Ÿซฃ They're technically legal, but they usually mean a mistake was made. Right now it warns under these circumstances:
    • An INTEGER SELECT construct has a CASE that can never be matched, since its lower value is greater than its upper value.
    • A LOGICAL SELECT construct has three CASE statements.
    • A TRANSFER specifies a source that is shorter than the destination.
    • The type of a function result is declared more than once with the same type. If -pedantic or standard-conforming mode is enabled, this is an error ๐Ÿ’€
    • A "CHARACTER" variable is declared with negative length.
    • With -fopenmp, for fixed-form source code, when an "omx" vendor-extension sentinel is encountered. (The equivalent "ompx", used in free-form source code, is diagnosed by default ๐Ÿ’…)
  • -Wtabs โ€” by default, tabs are accepted as whitespace, but tabs are not members of the Fortran Character Set ๐Ÿ™ƒ For continuation lines, a tab followed by a digit between 1 and 9 is supported. -Wtabs makes a warning get issued whenever a tab is encountered. Note, -Wtabs is active for -pedantic, -std=f95, -std=f2003, -std=f2008, -std=f2018, -std=f2023 and -Wall.
  • -Wundefined-do-loop โ€” warns if a DO loop with step either 1 or -1 yields an underflow or an overflow while an induction variable of the loop is iterating ๐ŸŒ€ Implied by -Wall.
  • -Wunderflow โ€” produces a warning when numerical constant expressions are encountered that UNDERFLOW during compilation ๐Ÿ“‰ Enabled by default.
  • -Wintrinsic-shadow โ€” warns if a user-defined procedure or module procedure has the same name as an intrinsic ๐Ÿฅธ In that case, an explicit interface, or an "EXTERNAL" or "INTRINSIC" declaration, might be needed so later calls get resolved to the procedure you actually want. This one is implied by -Wall.
  • -Wuse-without-only โ€” warns if a "USE" statement has no "ONLY" qualifier, which means it implicitly imports all public entities of the used module ๐Ÿ“ฆ
  • -Wunused-dummy-argument โ€” warns about unused dummy arguments ๐Ÿ—‘๏ธ Implied by -Wall.
  • -Wunused-parameter โ€” here's a plot twist: unlike gcc's meaning of this option, gfortran's version does not warn about unused dummy arguments (for that, see -Wunused-dummy-argument). Instead it warns about unused "PARAMETER" values ๐ŸŽญ -Wunused-parameter is implied by -Wextra if -Wunused or -Wall is also used.
  • -Walign-commons โ€” by default, gfortran warns about any time variables get padded for proper alignment inside a "COMMON" block ๐Ÿ“ You can turn this off with -Wno-align-commons. See also -falign-commons.
  • -Wfunction-elimination โ€” warns if any calls to impure functions get eliminated by the optimizations enabled by the -ffrontend-optimize option ๐Ÿงน Implied by -Wextra.
  • -Wrealloc-lhs โ€” warns when the compiler might insert code to allocate or reallocate an allocatable array variable of intrinsic type in intrinsic assignments ๐Ÿข In hot loops, the Fortran 2003 reallocation feature may hurt performance. If the array is already allocated with the correct shape, consider using a whole-array array-spec (e.g. "(:,:,:)") for the variable on the left-hand side to skip the reallocation check. Also, the warning sometimes shows up even when the compiler would optimize the reallocation checks away, like when the right-hand side contains the same variable multiplied by a scalar. See also -frealloc-lhs.
  • -Wrealloc-lhs-all โ€” warns when the compiler inserts code to allocate or reallocate an allocatable variable, including scalars and derived types ๐Ÿงฉ
  • -Wcompare-reals โ€” warns when comparing real or complex types for equality or inequality ๐Ÿ™…โ€โ™€๏ธ Implied by -Wextra.
  • -Wtarget-lifetime โ€” warns if the pointer in a pointer assignment might outlive its target โณ Implied by -Wall.
  • -Wzerotrip โ€” warns if a "DO" loop is known to execute zero times at compile time 0๏ธโƒฃ Implied by -Wall.
  • -Wdo-subscript โ€” warns if an array subscript inside a DO loop could lead to an out-of-bounds access, even when the compiler can't prove the statement actually runs ๐Ÿ‘€ Here's a classic example:
real a(3)
do i=1,4
  if (condition(i)) then
    a(i) = 1.2
  end if
end do

Implied by -Wextra.

  • -Werror โ€” turns all warnings into errors ๐Ÿ›‘

Some of these have no effect when compiling programs written in Fortran ๐Ÿคทโ€โ™€๏ธ


๐Ÿ› Options for debugging your program ๐Ÿ›

GNU Fortran has a bunch of special options for debugging your program ๐Ÿ”

  • -fdebug-aux-vars โ€” renames the internal variables created by the gfortran front end and makes them accessible to a debugger ๐Ÿชฒ The names of the internal variables then start with upper-case letters followed by an underscore. This is useful for debugging the compiler's code generation together with "-fdump-tree-original", and for debugging the executable program by using "-g" or "-ggdb3".
  • -ffpe-trap=list โ€” ๐Ÿฆ‹ okay so this one lets you pick which floating point exception traps get switched on! If one of the enabled exceptions pops off, a SIGFPE signal gets sent and the program gets aborted, leaving behind a core file that's super useful for debugging ๐Ÿ”ฅ. list is a (possibly empty) comma-separated list, and it's either none (to clear the set of trapped exceptions) or some combo of these: invalid (invalid floating point operation, like SQRT(-1.0) ๐Ÿ’€), zero (division by zero), overflow (overflow in a floating point operation), underflow (underflow in a floating point operation), inexact (loss of precision during an operation), and denormal (an operation performed on a denormal value). The first five are the five IEEE 754 exceptions. denormal is the odd one out: it's not part of IEEE 754, but it's available on some common architectures like x86 โœจ.

The first three exceptions (invalid, zero, and overflow) often mean something serious went wrong ๐Ÿ˜ญ. Unless your program has a plan for dealing with them, turning traps on for those three is probably a good idea ๐Ÿซถ.

If you use this option more than once on the command line, the lists get joined. So -ffpe-trap=list1 -ffpe-trap=list2 is the same as -ffpe-trap=list1,list2 ๐Ÿ’–.

Once an exception is enabled, you can't turn it off again (there's no negative form) unless you clear everything by specifying none ๐Ÿ™…โ€โ™€๏ธ.

Lowkey, most floating point operations lose some precision because of rounding, so -ffpe-trap=inexact is likely to be uninteresting in practice ๐Ÿฅฑ.

By default, no exception traps are enabled ๐Ÿ’ค.

  • -ffpe-summary=list โ€” ๐Ÿ“ฃ bestie, this one decides which floating-point exceptions get their flag status printed to ERROR_UNIT when STOP or ERROR STOP runs. list can be none, all, or a comma-separated list of invalid, zero, overflow, underflow, inexact and denormal. (Peek at -ffpe-trap if you need a refresher on what each exception means ๐Ÿงš.)

If you use it more than once on the command line, only the last one counts ๐Ÿคทโ€โ™€๏ธ.

By default, you get a summary for all exceptions except inexact ๐Ÿ’….

  • -fno-backtrace โ€” ๐Ÿ™ˆ when a serious runtime error shows up, or a deadly signal gets emitted (segmentation fault, illegal instruction, bus error, floating-point exception, and the other POSIX signals whose action is core), the Fortran runtime library tries to print a backtrace of the error. -fno-backtrace turns that backtrace generation off. Also, this option only has influence when compiling the Fortran main program ๐Ÿ’€.

These options affect how GNU Fortran searches for files specified by the INCLUDE directive, and where it looks for previously compiled modules ๐Ÿ—บ๏ธ.

They also affect the search paths that cpp uses when it preprocesses Fortran source ๐Ÿงš.

  • -Idir โ€” these affect how the INCLUDE directive gets interpreted (and the #include directive of the cpp preprocessor too) ๐ŸŽ€.

Also, the general behavior of -I and INCLUDE is pretty much the same as -I with #include in the cpp preprocessor, when it comes to looking for header.gcc files and other stuff like that ๐Ÿซถ.

This path is also used to search for .mod files when previously compiled modules are needed by a USE statement ๐Ÿ”.

  • -Jdir โ€” this one tells the compiler where to put .mod files for compiled modules ๐Ÿ“ฆ. It also gets added to the list of directories searched by a USE statement.

The default is the current directory ๐Ÿ“.

  • -fintrinsic-modules-path dir โ€” use this if your pre-compiled intrinsic modules aren't in the default location the compiler expects ๐Ÿ—‚๏ธ.

๐Ÿ”— Influencing the linking step ๐Ÿ”—

These options come into play when the compiler links object files into an executable output file. If the compiler isn't doing a link step, they do absolutely nothing ๐Ÿ™ƒ.

  • -static-libgfortran โ€” on systems that provide libgfortran as both a shared and a static library, this forces the use of the static version ๐Ÿ’ช. If no shared version of libgfortran was built when the compiler got configured, this option has no effect.
  • -static-libquadmath โ€” same vibe, but for libquadmath. On systems that provide it as a shared and a static library, this forces the static version. If no shared version of libquadmath was built when the compiler was configured, this option has no effect ๐ŸŒธ.
โš ๏ธ Heads up, bestie: the libquadmath runtime library is licensed under the GNU Lesser General Public License (LGPL), and linking it statically introduces requirements when you redistribute the resulting binaries. Read the fine print before you ship ๐Ÿ“œ.

๐ŸŒˆ Influencing runtime behavior ๐ŸŒˆ

These options affect the runtime behavior of programs compiled with GNU Fortran ๐ŸŽ€.

  • -fconvert=conversion โ€” this sets the representation of data for unformatted files ๐Ÿง. On most systems, the valid values for conversion are native (the default), swap (swap between big- and little-endian), big-endian (use big-endian representation for unformatted files), and little-endian (use little-endian representation for unformatted files).

On POWER systems that support -mabi=ieeelongdouble, there are extra options too, which can be combined with the others using commas ๐ŸŒŸ. They are:

  • -fconvert=r16_ieee โ€” use IEEE 128-bit format for REAL(KIND=16).
  • -fconvert=r16_ibm โ€” use IBM long double format for REAL(KIND=16).

This option only has an effect when it's used in the main program ๐Ÿ‘‘. The CONVERT specifier and the GFORTRAN_CONVERT_UNIT environment variable both override the default you set with -fconvert ๐Ÿ™Œ.

  • -frecord-marker=length โ€” this sets the length of record markers for unformatted files ๐Ÿ“. Valid values for length are 4 and 8, and the default is 4. This is different from older versions of gfortran, which used a default record marker length of 8 on most systems. If you want to read or write files that are compatible with earlier versions of gfortran, use -frecord-marker=8 ๐Ÿฆ‹.
  • -fmax-subrecord-length=length โ€” sets the maximum length for a subrecord ๐Ÿ’…. The max permitted value for length is 2147483639, which is also the default. Honestly it's only really useful for the gfortran testsuite ๐Ÿงช.
  • -fsign-zero โ€” when this is enabled, floating point numbers with a value of zero but the sign bit set get written as negative numbers in formatted output, and they're treated as negative in the SIGN intrinsic ๐Ÿ”ฅ. -fno-sign-zero does not print the negative sign of zero values (or values rounded to zero for I/O), and it regards zero as a positive number in the SIGN intrinsic, for compatibility with Fortran 77 ๐Ÿซถ. The default is -fsign-zero.

๐Ÿ› ๏ธ GNU Fortran Developer Options ๐Ÿ› ๏ธ

GNU Fortran has a bunch of special options that are used for debugging the GNU Fortran compiler itself ๐Ÿง‘โ€๐Ÿ’ป.

  • -fdump-fortran-global โ€” outputs a list of the global identifiers after they've been translated into middle-end representation ๐Ÿ”Ž.
  • -fdump-fortran-optimized โ€” outputs the parse tree after front-end optimization ๐ŸŒณ.
  • -fdump-fortran-original โ€” outputs the internal parse tree after the source program gets translated into internal representation ๐Ÿ“œ.
  • -fdump-parse-tree โ€” outputs the internal parse tree after the source program gets translated into internal representation ๐ŸŒฒ.
๐Ÿšจ -fdump-parse-tree is deprecated, so use -fdump-fortran-original instead.
โš ๏ธ For all of the -fdump-fortran-* options and -fdump-parse-tree: they're mostly useful for debugging the GNU Fortran compiler itself. The output they generate might change between releases, and they may also generate internal compiler errors for features that were only recently added ๐Ÿ˜ฌ.
  • -save-temps โ€” this stores the usual "temporary" intermediate files permanently ๐Ÿ’พ. They get named as auxiliary output files, as described under GCC -dumpbase and -dumpdir.
gfortran -save-temps -c foo.F90

This preprocesses the input file foo.F90 to foo.fii, compiles it to an intermediate foo.s, and then assembles it to the (implied) output file foo.o ๐Ÿงš.

gfortran -save-temps -S foo.F

This one saves the preprocessor output in foo.fi, and then compiles it to the (implied) output file foo.s ๐Ÿฆ‹.


๐ŸŽ€ Options for code generation conventions ๐ŸŽ€

These machine-independent options control the interface conventions used in code generation ๐Ÿ’–.

Most of them have both positive and negative forms, where the negative form of -ffoo would be -fno-foo. In the list below, only one of the forms is listed (the one that's not the default). You can figure out the other form by removing no- or adding it ๐Ÿ™ƒ.

  • -fno-automatic โ€” this treats each program unit (except those marked as RECURSIVE) as if the SAVE statement were specified for every local variable and array referenced in it ๐Ÿง . It doesn't affect common blocks. (Some Fortran compilers offer this option under the name -static or -save.) The default is -fautomatic, which uses the stack for local variables smaller than the value given by -fmax-stack-var-size. To use no static memory at all, use the option -frecursive ๐ŸŒ€.

Local variables or arrays that have an explicit SAVE attribute are silently ignored, unless you add the -pedantic option ๐Ÿ‘€.

  • -ff2c โ€” generates code that's designed to be compatible with code generated by g77 and f2c ๐Ÿง.

The calling conventions g77 uses (originally from f2c) are lowkey wild ๐Ÿ’… Functions that return default "REAL" have to actually return the C type "double", and "COMPLEX" functions hand their values back through an extra argument in the call, one that points to where the return value should be stored ๐Ÿซถ Under the default GNU calling conventions it's way simpler: default "REAL" functions return the C type "float", and "COMPLEX" functions return the GNU C type "complex" โœจ This option also implies -fsecond-underscore, unless you explicitly ask for -fno-second-underscore ๐ŸŽ€

It doesn't touch the code that interfaces with the libgfortran library, so that part stays the same ๐ŸŒธ

๐Ÿ’€ Caution, bestie: Don't mix Fortran code compiled with -ff2c with code compiled with the default -fno-f2c calling conventions. Calling "COMPLEX" or default "REAL" functions between program parts compiled with different calling conventions will break at execution time.
๐Ÿ’€ Caution: This will break code that passes intrinsic functions of default "REAL" or "COMPLEX" type as actual arguments, because the library implementations use the -fno-f2c calling conventions.

โœจ -fno-underscoring โœจ

This one tells GNU Fortran to stop slapping underscores onto the names of entities from your Fortran source file ๐Ÿ™ˆ

With -funderscoring in effect, GNU Fortran appends one underscore to external names. It does this so your code plays nicely with the object code made by lots of UNIX Fortran compilers ๐Ÿฆ‹

๐Ÿ’€ Caution: GNU Fortran's default behavior is incompatible with f2c and g77. If you want object files compiled with GNU Fortran to be compatible with object code made by those tools, use the -ff2c option.

Using -fno-underscoring isn't recommended unless you're experimenting with things like plugging GNU Fortran into existing system environments (vis-ร -vis existing libraries, tools, and so on) ๐Ÿ“

Here's an example. With -funderscoring, and assuming that j() and max_count() are external functions while "my_var" and "lvar" are local variables, a statement like this:

I = J() + MAX_COUNT (MY_VAR, LVAR)

gets implemented as something akin to:

i = j_() + max_count_(&my_var, &lvar);

With -fno-underscoring, that same statement is implemented as:

i = j() + max_count(&my_var, &lvar);

Using -fno-underscoring lets you specify user-defined names directly while debugging and when interfacing GNU Fortran code with other languages ๐Ÿงš

Just because the names match doesn't mean the interface GNU Fortran implements for an external name matches the interface some other language implements for that same name. Getting code from GNU Fortran to link with code from some other compiler, by this method or any other, can be only a small part of the overall solution. Getting the code from both compilers to agree on things other than naming can take serious effort, and unlike naming disagreements, linkers normally can't detect disagreements in those other areas ๐Ÿ˜ญ

Also, with -fno-underscoring, the lack of appended underscores creates a very real chance that a user-defined external name will clash with a name in a system library. That could make unresolved-reference bugs super hard to find in some cases, since they might only happen at program run time and show up as buggy behavior at run time ๐Ÿ’€

In future versions of GNU Fortran, the goal is to improve naming and linking so that debugging always uses the names as they appear in the source. Even if the linker sees mangled names (to prevent accidental linking between procedures with incompatible interfaces), you'd still be debugging with the names you wrote ๐Ÿ‘‘

โœจ -fsecond-underscore โœจ

By default, GNU Fortran appends an underscore to external names. With this option, GNU Fortran appends two underscores to names that already contain underscores, and one underscore to external names that don't. It also appends two underscores to internal names that contain underscores, so they can't collide with external names ๐ŸŒˆ

This option has no effect if -fno-underscoring is in effect. It's implied by the -ff2c option ๐Ÿซถ

So with this option, an external name such as "MAX_COUNT" is implemented as a reference to the link-time external symbol "max_count__", instead of "max_count_". This is required for compatibility with g77 and f2c, and it's implied by use of the -ff2c option ๐Ÿ’–

โœจ -fcoarray=<keyword> โœจ

Pick one of these keywords:

  • none โ€” Disables coarray support. Using coarray declarations and image-control statements will give you a compile-time error. (Default) ๐Ÿ™…
  • single โ€” Single-image mode, meaning num_images() is always one โœจ
  • lib โ€” Library-based coarray parallelization. You'll need to link a suitable GNU Fortran coarray library ๐Ÿ“š

โœจ -fcheck=<keyword> โœจ

This turns on run-time checks. The argument is a comma-delimited list of the keywords below. Put no- in front of a check to turn it off if an earlier specification switched it on ๐Ÿ”

  • all โ€” Enables every run-time test of -fcheck ๐Ÿ‘‘
  • array-temps โ€” Warns at run time when passing an actual argument required generating a temporary array. This info is sometimes handy for optimization, so you can avoid those temporaries ๐Ÿงน
    • Heads up: the warning only gets printed once per location ๐Ÿ™ˆ
  • bits โ€” Turns on run-time checks for invalid arguments to the bit manipulation intrinsics ๐Ÿง 
  • bounds โ€” Turns on run-time checks for array subscripts against the declared minimum and maximum values. It also checks array indices for assumed and deferred shape arrays against the actual allocated bounds, and makes sure all string lengths are equal for character array constructors without an explicit typespec ๐Ÿ“
    • Some checks require that -fcheck=bounds is set for the compilation of the main program ๐Ÿ’…
    • Note: in the future this may also include other forms of checking, e.g., checking substring references ๐Ÿ”ฎ
  • do โ€” Turns on run-time checks for invalid modification of loop iteration variables ๐Ÿ”
  • mem โ€” Turns on run-time checks for memory allocation.
    • Note: This option doesn't affect explicit allocations using the ALLOCATE statement. Those are always checked โœ…
  • pointer โ€” Turns on run-time checks for pointers and allocatables ๐ŸŽฏ
  • recursion โ€” Turns on run-time checks for recursively called subroutines and functions that aren't marked as recursive. See also -frecursive.
    • Note: This check doesn't work for OpenMP programs, and it's disabled if you use it together with -frecursive and -fopenmp ๐Ÿ˜ญ

Example time! ๐ŸŽ€ Say you have a file called foo.f90. This command:

gfortran -fcheck=all,no-array-temps foo.f90

will compile the file with all checks enabled, as specified above, except for the warnings about generated array temporaries ๐Ÿ’–

โœจ -fbounds-check โœจ

This is a deprecated alias for -fcheck=bounds ๐Ÿฅ€

โœจ -ftail-call-workaround, -ftail-call-workaround=n โœจ

Okay, this one's a bit of a drama queen ๐ŸŽญ Some C interfaces to Fortran code violate the gfortran ABI by omitting the hidden character length arguments as described in

This can lead to crashes, because pushing arguments for tail calls can overflow the stack ๐Ÿ’€

To give existing binary packages a workaround, this option disables tail call optimization for gfortran procedures with character arguments. Here's how the levels break down:

  • -ftail-call-workaround=2 disables tail call optimization in all gfortran procedures with character arguments.
  • -ftail-call-workaround=1, or just plain -ftail-call-workaround, only disables it in gfortran procedures with character arguments that call implicitly prototyped procedures.

Using this option can lead to problems, including crashes due to insufficient stack space ๐Ÿ˜ต

๐Ÿ’€ Strongly recommended: fix the code in question! The -fc-prototypes-external option can generate prototypes that conform to gfortran's ABI, which you can then include in your source code.
๐Ÿฅบ Support for this option will likely be withdrawn in a future release of gfortran.

The negative form, -fno-tail-call-workaround or equivalent -ftail-call-workaround=0, can be used to disable this option ๐Ÿ™…

Right now the default is -ftail-call-workaround, but this will change in future releases ๐ŸŒธ

โœจ -fcheck-array-temporaries โœจ

Another deprecated alias, this time for -fcheck=array-temps ๐Ÿฅ€

โœจ -fmax-array-constructor=n โœจ

This option raises the upper limit allowed in array constructors. The code below needs this option to expand the array at compile time ๐Ÿงš

program test
implicit none
integer j
integer, parameter :: n = 100000
integer, parameter :: i(n) = (/ (2*j, j = 1, n) /)
print '(10(I0,1X))', i
end program test
๐Ÿ’€ Caution: This option can lead to long compile times and excessively large object files. Know what you're signing up for, bestie!

The default value for n is 65535 ๐Ÿ”ข

โœจ -fmax-stack-var-size=n โœจ

This option sets the size in bytes of the largest array that gets put on the stack. If an array is bigger than that, static memory gets used instead (except in procedures marked as RECURSIVE). If you want recursive procedures that don't have a RECURSIVE attribute, or you're writing parallel programs, use -frecursive. If you never want to use the stack, use -fno-automatic ๐Ÿฅž

This option currently only affects local arrays declared with constant bounds, and it may not apply to all character variables. Future versions of GNU Fortran may improve this behavior ๐Ÿ”ฎ

The default value for n is 65536 ๐Ÿ’œ

โœจ -fstack-arrays โœจ

Adding this option makes the Fortran compiler put all arrays of unknown size, plus array temporaries, onto stack memory. If your program uses very large local arrays, you might have to raise your runtime limits for stack memory on some operating systems ๐Ÿ“ˆ This flag is enabled by default at optimization level -Ofast, unless -fmax-stack-var-size is specified โญ

  • -fpack-derived โ€” okay bestie, this one tells GNU Fortran to pack derived type members as closely together as possible ๐Ÿ“ฆ. Heads up: code compiled with it is likely to be incompatible with code compiled without it, and it may run slower ๐Ÿ’€.
  • -frepack-arrays โ€” so sometimes GNU Fortran passes assumed shape array sections through a descriptor that describes a noncontiguous chunk of memory ๐Ÿงฉ. This flag tacks code onto the very start of the function (the prologue) that repacks the data into one contiguous block at runtime ๐Ÿงบ.
    • The payoff is faster array accesses โœจ. The catch is it can add serious overhead to the function call, especially when the data being passed is noncontiguous ๐Ÿ˜ญ.
  • -fshort-enums โ€” this one is for playing nice with C code that was compiled with -fshort-enums ๐Ÿค. GNU Fortran picks the smallest INTEGER kind that a given enumerator set fits into, then gives every enumerator in that set that kind ๐ŸŽ€.
  • -finline-arg-packing โ€” when you pass an assumed-shape argument of a procedure as an actual argument to an assumed-size or explicit size argument, or to a procedure with no explicit interface, that argument may have to get packed (aka shoved into contiguous memory) ๐Ÿ“ฆ. The classic example is the call to foo here:
subroutine foo(a)
   real, dimension(*) :: a
end subroutine foo
subroutine bar(b)
   real, dimension(:) :: b
   call foo(b)
end subroutine bar

When -finline-arg-packing is in effect, that packing gets done with inline code ๐Ÿง . That allows more optimization, but the code gets bigger. It's implied by any -O option except -Os (optimizing for size) ๐Ÿ‹๏ธ. If your code has a very large number of arguments that need packing, code size and compilation time can go totally off the rails ๐Ÿ™ƒ, so it may be better to disable it. You can find instances of packing by using -Warray-temporaries.

  • -fexternal-blas โ€” gfortran will make calls to BLAS functions for some matrix operations like MATMUL, instead of using its own algorithms, as long as the matrices are bigger than a given limit (see -fblas-matmul-limit) ๐Ÿงฎ. This can be super profitable if an optimized vendor BLAS library is available ๐Ÿ”ฅ. The BLAS library has to be specified at link time ๐Ÿ”—.
  • -fblas-matmul-limit=n โ€” only significant when -fexternal-blas is in effect ๐ŸŽฏ. Matrix multiplication with matrices of size larger than (or equal to) n gets done by calls to BLAS functions, while smaller ones are handled by gfortran's internal algorithms. If the matrices involved aren't square, the size comparison uses the geometric mean of the dimensions of the argument and result matrices ๐Ÿ“.
    • The default value for n is 30 ๐Ÿ’….
  • -finline-matmul-limit=n โ€” when front-end optimization is active, some calls to the MATMUL intrinsic function get inlined ๐Ÿช„. This can bump up code size if the matrix size can't be determined at compile time, because code for both cases gets generated ๐Ÿ“ˆ. Setting -finline-matmul-limit=0 disables inlining in all cases ๐Ÿšซ. Setting it to a value n produces inline code for matrices up to size n โœจ. If the matrices aren't square, the size comparison uses the geometric mean of the dimensions of the argument and result matrices ๐Ÿ“.
    • The default value for n is 30. The -fblas-matmul-limit can be used to change this value ๐Ÿฆ‹.
  • -frecursive โ€” allows indirect recursion by forcing all local arrays to be allocated on the stack ๐Ÿ“š. This flag can't be used together with -fmax-stack-var-size= or -fno-automatic ๐Ÿ™….
  • -finit-local-zero, -finit-derived, -finit-integer=n, -finit-real=<zero|inf|-inf|nan|snan>, -finit-logical=<true|false>, -finit-character=n โ€” initialization flags ๐ŸŒฑ
    • -finit-local-zero sets local INTEGER, REAL, and COMPLEX variables to zero, LOGICAL variables to false, and CHARACTER variables to a string of null bytes 0๏ธโƒฃ.
    • The finer-grained flags are -finit-integer=n, -finit-real=<zero|inf|-inf|nan|snan> (which also initializes the real and imaginary parts of local COMPLEX variables), -finit-logical=<true|false>, and -finit-character=n (where n is an ASCII character value) ๐ŸŽ›๏ธ.
    • With -finit-derived, components of derived type variables get initialized according to these flags. Components whose type isn't covered by an explicit -finit-* flag are treated the same as with -finit-local-zero ๐Ÿงธ.
    • These options do not initialize:
      • objects with the POINTER attribute
      • allocatable arrays
      • variables that appear in an EQUIVALENCE statement
    • (These limitations may be removed in future releases ๐Ÿคž.)
    • -finit-real=nan initializes REAL and COMPLEX variables with a quiet NaN. For a signalling NaN, use -finit-real=snan. Note, however, that compile-time optimizations may convert them into a quiet NaN, and trapping needs to be enabled (e.g. via -ffpe-trap) โš ๏ธ.
    • -finit-integer parses the value into an integer of type INTEGER(kind=C_LONG) on the host. That value then gets assigned to the integer variables in the Fortran code, which might wrap around if the value is too large for the kind ๐ŸŒ€.
    • Enabling any of the -finit-* options silences warnings that -Wuninitialized would have emitted for the affected local variables ๐Ÿ”‡.
  • -falign-commons โ€” by default, gfortran enforces proper alignment of all variables in a COMMON block by padding them as needed ๐Ÿ“. On certain platforms this is mandatory, and on others it boosts performance ๐Ÿš€. If a COMMON block isn't declared with consistent data types everywhere, that padding can cause trouble, and -fno-align-commons can be used to disable automatic alignment ๐Ÿ™…. Use the same form of this option for all files that share a COMMON block. To avoid potential alignment issues in COMMON blocks, order your objects from largest to smallest ๐Ÿงฑ.
  • -fno-protect-parens โ€” by default, parentheses in expressions are honored at all optimization levels, so the compiler doesn't do any re-association ๐Ÿ™Œ. Using -fno-protect-parens lets the compiler reorder REAL and COMPLEX expressions to produce faster code ๐ŸŽ๏ธ. For that re-association optimization, -fno-signed-zeros and -fno-trapping-math need to be in effect โš ๏ธ. The parentheses protection is enabled by default, unless -Ofast is given.
  • -frealloc-lhs โ€” an allocatable left-hand side of an intrinsic assignment is automatically (re)allocated if it's either unallocated or has a different shape ๐Ÿชฃ. This is enabled by default except when -std=f95 is given. See also -Wrealloc-lhs ๐Ÿ‘€.
  • -faggressive-function-elimination โ€” functions with identical argument lists get eliminated within statements, regardless of whether they're marked PURE or not ๐Ÿ—‘๏ธ. For example, in:
a = f(b,c) + f(b,c)

there will only be a single call to f ๐ŸŽฏ. This option only works if -ffrontend-optimize is in effect.

  • -ffrontend-optimize โ€” performs front-end optimization by manipulating parts of the Fortran parse tree ๐ŸŒณ. It's enabled by default by any -O option except -O0 and -Og. The optimizations this turns on include:
    • inlining calls to MATMUL,
    • elimination of identical function calls within expressions,
    • removing unnecessary calls to TRIM in comparisons and assignments,
    • replacing TRIM(a) with a(1:LEN_TRIM(a)), and
    • short-circuiting of logical operators (.AND. and .OR.).
    • It can be deselected by specifying -fno-frontend-optimize ๐Ÿ™…โ€โ™€๏ธ.
  • -ffrontend-loop-interchange โ€” attempts to interchange loops in the Fortran front end where it's profitable ๐Ÿ”„. Enabled by default by any -O option. At the moment, this option only affects FORALL and DO CONCURRENT statements with several forall triplets ๐ŸŽ€.

โœจ ENVIRONMENT โœจ

Right now, gfortran doesn't make use of any environment variables of its own to control how it operates, beyond the ones that affect the operation of gcc ๐ŸŒท.

๐Ÿž BUGS ๐Ÿž

Want to report something? The instructions for reporting bugs live at <file:///usr/share/doc/gcc-14/README.Bugs> ๐Ÿ•ต๏ธโ€โ™€๏ธ.

๐Ÿ”— SEE ALSO ๐Ÿ”—

gpl(7), gfdl(7), fsf-funding(7), cpp(1), gcov(1), gcc(1), as(1), ld(1), gdb(1), dbx(1), and the Info entries for gcc, cpp, gfortran, as, ld, binutils and gdb ๐Ÿ“š.

๐Ÿ‘ฉโ€๐Ÿ’ป AUTHOR ๐Ÿ‘ฉโ€๐Ÿ’ป

See the Info entry for gfortran for contributors to GCC and GNU Fortran ๐Ÿซถ.

Copyright (c) 2004-2024 Free Software Foundation, Inc. ๐Ÿ’œ

You're totally allowed to copy, distribute, and/or modify this document under the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation ๐Ÿ“œ. The Invariant Section is "Funding Free Software," the Front-Cover Text is (a) below, and the Back-Cover Text is (b) below. A copy of the license is included in the gfdl(7) man page.

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

A GNU Manual

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

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

That's the whole page, bestie! ๐ŸŽ€ It's from gcc-14, dated 2024-04-12, and it's GFORTRAN(1) all the way ๐Ÿ’…โœจ Go be iconic ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from