GFORTRAN(1)

โœจ gfortran(1): the GNU manual page, bestie ๐Ÿ’–

Okay so this is the gfortran page from the GNU manual ๐Ÿงš It's the compiler for Fortran, and this is part 1 of the tea โ˜•

โœจ NAME โœจ

gfortran is the GNU Fortran compiler ๐Ÿ’…

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

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

Only the most useful options are listed here, so check below for the rest ๐Ÿฆ‹

๐Ÿ’– DESCRIPTION ๐Ÿ’–

The gfortran command supports all the options that gcc supports ๐ŸŒˆ This page only documents the options that are specific to GNU Fortran, so that's what we're focusing on, bestie ๐Ÿซถ

Every GCC and GNU Fortran option is accepted by both gfortran and gcc, plus any other drivers built at the same time (like g++) ๐Ÿ‘‘ Adding GNU Fortran to the GCC distribution means all the relevant drivers accept GNU Fortran options. It's giving team effort ๐Ÿ’œ

Some options come in positive and negative forms. The negative form of -ffoo is -fno-foo โœจ This manual only documents whichever of the two is not the default, so keep that in mind ๐Ÿ™ˆ

โœจ OPTIONS โœจ

Here's the summary of every option that's specific to GNU Fortran, grouped by type ๐Ÿ“ The explanations come after this list, 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
-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 -fdump-fortran-optimized -fdump-fortran-original
-fdebug-aux-vars -fdump-fortran-global -fdump-parse-tree
-ffpe-trap=list -ffpe-summary=list

Directory Options

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

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

๐ŸŒˆ Options controlling Fortran dialect ๐ŸŒˆ

These options control the details of the Fortran dialect that the compiler accepts ๐Ÿ’…

  • -ffree-form, -ffixed-form โ€” This sets the layout your source file uses ๐Ÿฆ‹ Free form arrived in Fortran 90, and fixed form was the traditional layout in older Fortran programs. If you don't pick either one, the compiler figures out the source form from the file extension.
  • -fall-intrinsics โ€” This makes every intrinsic procedure work, including the GNU-specific extensions โœจ It's super useful alongside -std= if you want standard compliance but still want the full set of intrinsics gfortran has. The catch: -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 mismatched arguments, either compared to the procedure definition or between different calls ๐Ÿ™ˆ That code doesn't conform to the standard 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 a single occurrence per argument gets flagged. -fallow-argument-mismatch is implied by -std=legacy.
Using this option is strongly discouraged, bestie ๐Ÿ˜ญ You can write standard-conforming code that allows different argument types by using an explicit interface and TYPE(*).
  • -fallow-invalid-boz โ€” A BOZ literal constant can show up in a few contexts in standard-conforming Fortran ๐ŸŒธ This option turns the error into a warning and lets a BOZ literal constant appear where the Fortran standard would normally ban it.
  • -fd-lines-as-code, -fd-lines-as-comments โ€” These give special treatment to lines starting with "d" or "D" in fixed form sources ๐Ÿงš With -fd-lines-as-code, they're treated as if the first column had a blank in it. With -fd-lines-as-comments, they're treated as comment lines.
  • -fdec โ€” DEC compatibility mode ๐Ÿ’€ This turns on extensions and other features that copy the default behavior of older compilers (like DEC). These features are non-standard, so avoid them at all costs ๐Ÿ™… For details on GNU Fortran's version of these extensions, check the full documentation. This switch also turns on: -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. If -fd-lines-as-code or -fd-lines-as-comments aren't set, then -fdec also sets -fd-lines-as-comments ๐ŸŽ€
  • -fdec-char-conversions โ€” Lets you use character literals in assignments and "DATA" statements for non-character variables ๐Ÿ’–
  • -fdec-structure โ€” Enables DEC "STRUCTURE" and "RECORD", plus "UNION", "MAP", and the dot ('.') as a member separator, on top of '%' ๐Ÿ“ This is only here for compatibility. Where you can, use Fortran 90 derived types instead.
  • -fdec-intrinsic-ints โ€” Enables the B/I/J/K kind variants of existing integer functions, like BIAND, IIAND, JIAND, and so on ๐Ÿ”ฅ The full documentation has the complete list of intrinsics.
  • -fdec-math โ€” Enables legacy math intrinsics like COTAN and the degree-valued trig functions (like TAND, ATAND, and so on) so older code keeps working ๐ŸŒˆ
  • -fdec-static โ€” Enables DEC-style STATIC and AUTOMATIC attributes, so you can explicitly say how variables and other objects are stored ๐Ÿ‘‘
  • -fdec-include โ€” Lets INCLUDE parse as a statement as well as an INCLUDE line โœจ When it's parsed as a statement, INCLUDE doesn't have to sit on a single line and can use line continuations.
  • -fdec-format-defaults โ€” Lets you use the format specifiers F, G, and I without width specifiers, and default widths get used instead ๐Ÿฆ‹
  • -fdec-blank-format-item โ€” Enables a blank format item at the end of a format specification, meaning there's nothing after the final comma ๐Ÿซถ
  • -fdollar-ok โ€” Allows $ as a valid non-first character in a symbol name ๐Ÿ’… Symbols that start with $ get rejected, since it's unclear which implicit typing rules should apply (different vendors do different things). Using $ in "IMPLICIT" statements is also rejected.
  • -fbackslash โ€” Changes how backslashes work in string literals, from a single backslash character to "C-style" escape characters ๐ŸŒธ These combos get expanded: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\\", and "\0". They 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, "\x"nn, "\u"nnnn, and "\U"nnnnnnnn (where each n is a hexadecimal digit) get translated into the Unicode characters for those code points ๐ŸŒˆ Every other combo of a character preceded by \ stays unexpanded.
  • -fmodule-private โ€” 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 โ€” Sets the column after which characters get ignored on typical fixed-form lines in the source file ๐Ÿงš Unless you use -fno-pad-source, it also sets the column through which spaces get assumed (as if the line were padded out 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 (matching the "extended-source" options in some popular compilers) โœจ n can also be none, which means the whole line is meaningful and continued character constants never get implicit spaces added to fill out the line. -ffixed-line-length-0 does the exact same thing as -ffixed-line-length-none.
  • -fno-pad-source โ€” By default, fixed-form lines get spaces assumed (as if padded to that length) after the ends of short fixed-form lines ๐Ÿ’œ That doesn't happen if you use -ffixed-line-length-0, -ffixed-line-length-none, or -fno-pad-source. With any of those options, continued character constants never get implicit spaces appended to fill out the line.

_to be continued in part 2 ๐Ÿฆ‹_

  • -ffree-line-length-n โ€” okay so this one sets the column where the compiler stops reading typical free-form lines in your source file. Anything past that column gets ignored ๐Ÿซ  The default is 132, and n can be none if you want the entire line to count โœจ Also, -ffree-line-length-0 is exactly the same as -ffree-line-length-none ๐Ÿ’…
  • -fmax-identifier-length=n โ€” sets the maximum identifier length you're allowed ๐Ÿฆ‹ 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 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 โ€” enables the OpenACC extensions ๐Ÿ”ฅ This covers !$acc directives in free form, plus c$acc, *$acc and !$acc directives in fixed form. It also includes the !$ conditional compilation sentinels in free form and the c$, *$ and !$ sentinels in fixed form. When linking, it also makes sure the OpenACC runtime library gets linked in ๐Ÿซถ
  • -fopenmp โ€” enables the OpenMP extensions ๐Ÿ‘‘ This covers !$omp directives in free form, plus c$omp, *$omp and !$omp directives in fixed form. It also includes the !$ conditional compilation sentinels in free form and the c$, *$ and !$ sentinels in fixed form. When linking, it also makes sure the OpenMP runtime library gets linked in. Oh, and -fopenmp implies -frecursive ๐Ÿ’–
  • -fno-range-check โ€” turns off range checking on the results of simplifying constant expressions during compilation ๐Ÿ™ˆ By default, GNU Fortran errors at compile time when it simplifies a = 1. / 0. With this option, there's no error, and a gets the value +Infinity. If an expression evaluates to something outside the relevant range of ["-HUGE()":"HUGE()"], it 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 โ€” makes the default integer and logical types 8 bytes wide ๐Ÿ“ It 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 โ€” makes the default real type 8 bytes wide โœจ It also changes the kind of non-double real constants like 1.0. It bumps the default width of DOUBLE PRECISION and double real constants like 1.d0 up 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 โ€” makes the default real type 10 bytes wide ๐ŸŒˆ It also changes the kind of non-double real constants like 1.0. It bumps the default width of DOUBLE PRECISION and double real constants like 1.d0 up 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 โ€” makes the default real type 16 bytes wide ๐ŸŽ€ It also changes the kind of non-double real constants like 1.0. It bumps the default width of DOUBLE PRECISION and double real constants like 1.d0 up 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 8 bytes wide ๐Ÿฆ‹ 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 isn't available, you'll get an error. Areas of possible concern include calls to external procedures, alignment in EQUIVALENCE and/or COMMON, generic interfaces, BOZ literal constant conversion, and I/O. Inspecting the intermediate representation of the translated Fortran code, produced by -fdump-tree-original, is suggested.
โš ๏ธ Bestie, this one needs to be used with care, and it may not be suitable for your codes ๐Ÿ˜ญ
  • -freal-4-real-8, -freal-4-real-10, -freal-4-real-16, -freal-8-real-4, -freal-8-real-10, -freal-8-real-16 โ€” these promote all REAL(KIND=M) entities to REAL(KIND=N) entities ๐Ÿ‘‘ If REAL(KIND=N) isn't available, you'll get an error. The -freal-4- flags also affect the default real kind, and the -freal-8- flags also affect the double-precision real kind. Every other real-kind type is unaffected. 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. 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. Inspecting the intermediate representation of the translated Fortran code, produced by -fdump-fortran-original or -fdump-tree-original, is suggested.
โš ๏ธ These options should be used with care, and they may not be suitable for your codes ๐Ÿซ 
  • -std=std โ€” tell it which standard your program is supposed to follow ๐Ÿ“œ The options are f95, f2003, f2008, f2018, gnu, or legacy. The default is gnu, which is a superset of the latest Fortran standard that includes all the extensions GNU Fortran supports. You'll still get warnings for obsolete extensions that aren't recommended in new code. The legacy value is basically the same but without those warnings for obsolete extensions, so it can be handy for old non-standard programs. f95, f2003, f2008, and f2018 give you strict conformance to the Fortran 95, Fortran 2003, Fortran 2008, and Fortran 2018 standards, respectively. You get errors for any extension beyond that language standard, and warnings for Fortran 77 features that are still permitted but obsolescent in later standards.
โš ๏ธ The deprecated option -std=f2008ts acts as an alias for -std=f2018. It's only there for backwards compatibility with earlier gfortran versions, so please don't use it anymore ๐Ÿ’€
  • -ftest-forall-temp โ€” boosts test coverage by forcing most forall assignments to use a temporary ๐Ÿงช

๐Ÿ’… Enable and customize preprocessing ๐Ÿ’…

Many Fortran compilers, GNU Fortran included, let you pass your 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 runs 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 it would run automatically, use -nocpp.

If a preprocessed file pulls in another file with the Fortran INCLUDE statement, the included file is not preprocessed. If you want included files preprocessed, use the equivalent preprocessor statement #include instead ๐Ÿฆ‹

If GNU Fortran invokes the preprocessor, __GFORTRAN__ is defined โœจ The macros __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ can be used to figure out the compiler version. See Top,,Overview,cpp,The C Preprocessor for details.

GNU Fortran supports a bunch of INTEGER and REAL kind types in addition to the kind types the Fortran standard requires ๐ŸŒˆ Which ones you get is architecture dependent. These pre-defined preprocessor macros let you conditionally include code for those extra kind types: __GFC_INT_1__, __GFC_INT_2__, __GFC_INT_8__, __GFC_INT_16__, __GFC_REAL_10__, and __GFC_REAL_16__.

CPP is the de-facto standard for preprocessing Fortran code, but Part 3 of the Fortran 95 standard (ISO/IEC 1539-3:1998) defines Conditional Compilation. That one isn't widely used and GNU Fortran doesn't directly support it ๐Ÿ™ƒ If you need to preprocess files like that, you can use the program coco, found at <http://www.daniellnagle.com/coco.html>.

The following options control preprocessing of Fortran code ๐ŸŽ€

  • -cpp, -nocpp โ€” -cpp enables preprocessing ๐Ÿ’– The preprocessor is automatically invoked if the file extension is .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 or .F08. Use this option to manually enable preprocessing of any kind of Fortran file. To disable preprocessing of files with any of those extensions, use the negative form, -nocpp. The preprocessor runs in traditional mode. Any file-format restrictions, especially the limits on line length, also apply to the preprocessed output, 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 all the macros defined during the preprocessor run, predefined ones included ๐Ÿ” This is a great way to see what's predefined in your version of the preprocessor. Assuming you have no file foo.f90, run this:
touch foo.f90; gfortran -cpp -E -dM foo.f90

That'll show all the predefined macros ๐Ÿงš

  • -dD โ€” okay so this one is like -dM but with two twists ๐Ÿ’… it skips the predefined macros, and it spits out both the #define directives and the preprocessing result. Both go to standard output ๐Ÿ–จ๏ธโœจ
  • -dN โ€” same vibe as -dD, but it only gives you the macro names and skips the expansions ๐Ÿฆ‹
  • -dU โ€” lowkey the most selective one ๐Ÿ‘‘ it's like dD, except it only outputs macros that actually get expanded or get tested in preprocessor directives. The output waits until the macro gets used or tested, and #undef directives also show up for macros that were tested but were undefined at that point ๐Ÿซถ
  • -dI โ€” adds #include directives to the preprocessing output ๐ŸŒธ
  • -fworking-directory โ€” the preprocessor will emit linemarkers that tell the compiler what the current working directory was during preprocessing ๐Ÿ—บ๏ธ after the initial linemarker, it emits a second one with the working directory followed by two slashes. GCC uses that directory (if it's there in the preprocessed input) as the working directory in some debugging information formats. This is implicitly turned on when debugging info is enabled, but you can block it with the negated form -fno-working-directory. If -P is in your command line, this option does nothing, because no #line directives get emitted whatsoever ๐Ÿ’€
  • -idirafter dir โ€” searches dir for include files, but only after all the -I directories and the standard system directories are exhausted ๐Ÿงš dir gets treated as a system include directory. If dir begins with =, that = gets swapped for the sysroot prefix. See --sysroot and -isysroot
  • -imultilib dir โ€” uses dir as a subdirectory of the directory that holds the target-specific C++ headers ๐Ÿ“
  • -iprefix prefix โ€” sets prefix as the prefix for later -iwithprefix options. If the prefix is a directory, make sure you include the final / ๐ŸŽ€
  • -isysroot dir โ€” basically the --sysroot option, except it only applies to header files. Check the --sysroot option for more info โœจ
  • -iquote dir โ€” searches dir only for headers requested with #include "file". It won't search these for #include <file>. This happens before all the -I directories and the standard system directories. If dir begins with =, that = gets replaced with 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 ones ๐ŸŒˆ if dir begins with =, that = gets replaced with the sysroot prefix. See --sysroot and -isysroot
  • -nostdinc โ€” do not search the standard system directories for header files ๐Ÿ™…โ€โ™€๏ธ only the directories you gave with -I (plus the directory of the current file, if that applies) get searched
  • -undef โ€” doesn't predefine any system-specific or GCC-specific macros ๐Ÿงผ the standard predefined macros stay defined though
  • -Apredicate=answer โ€” makes an assertion with the predicate predicate and the answer answer. This is the preferred form over the older -A predicate(answer) (which still works!) because it doesn't use shell special characters ๐Ÿš
  • -A-predicate=answer โ€” cancels an assertion with the predicate predicate and the answer answer ๐Ÿšซ
  • -C โ€” don't discard comments! All comments get passed through to the output, except the ones inside processed directives, which get deleted along with the directive ๐Ÿ’ฌ

Be prepared for side effects with -C, bestie. It makes the preprocessor treat comments as tokens in their own right. So, 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 is no longer a # ๐Ÿ˜ญ

โš ๏ธ Warning: this currently handles C-style comments only. The preprocessor does not yet recognize Fortran-style comments.
  • -CC โ€” don't discard comments, including during macro expansion ๐Ÿ” this is like -C, except comments inside macros also get passed through to the output wherever that macro gets expanded.

On top of the -C side effects, -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 ๐Ÿ™ˆ -CC is mostly 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 showed up during translation phase three in a #define directive. Notably, the definition gets cut off at embedded newline characters โœ‚๏ธ

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

Want a function-like macro on the command line? Put its argument list in parentheses before the equals sign (if there is one). Parentheses mean stuff to most shells, so you'll need to quote the option. With sh and csh, "-D'name(args...)=definition'" works ๐Ÿซถ

-D and -U options are processed in the order they appear on the command line. All -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 stuff. Each name is indented to show how deep it sits in the #include stack ๐Ÿชœ
  • -P โ€” inhibits linemarker generation in the preprocessor output ๐Ÿšซ๐Ÿ“ this might be useful if you're running the preprocessor on something that isn't C code and the program receiving it might get confused by the linemarkers ๐ŸŒธ
  • -Uname โ€” cancels any previous definition of name, whether it was built in or set with a -D option ๐Ÿงฝ

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

Errors are diagnostic messages that say the GNU Fortran compiler can't compile that bit of source code ๐Ÿ˜ค The compiler keeps going anyway to report more errors so you can debug, but it won't produce any compiled output.

Warnings are diagnostic messages about constructions that aren't inherently wrong, but are risky or hint that there's probably a bug ๐Ÿ‘€ Unless -Werror is specified, they won't stop the program from compiling.

You can request lots of specific warnings with options starting with -W. For example, -Wimplicit asks for warnings on implicit declarations. Each specific warning option also has a negative form starting with -Wno- that turns the warning off, like -Wno-implicit. This manual only lists one of the two forms, whichever one isn't the default ๐Ÿค“

These options control the amount and kinds of errors and warnings GNU Fortran produces ๐Ÿ’…

  • -fmax-errors=n โ€” caps the number of error messages at n. Once you hit that, 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 ๐Ÿ” it does generate module files for each module in the code, but no other output file.
  • -Wpedantic, -pedantic โ€” issues warnings for uses of Fortran extensions ๐Ÿง -pedantic also applies to C-language constructs when they show up in GNU Fortran source files, like using \e in a character constant inside a directive such as "#include".

Valid Fortran programs should compile fine with or without this option. Without it, though, certain GNU extensions and traditional Fortran features are also supported. With this option, a lot of them get rejected ๐Ÿ™…โ€โ™€๏ธ

Some people try to use -pedantic to check programs for conformance. They quickly find it doesn't do exactly what they want: it catches some nonstandard practices, but not all of them. Still, improvements to GNU Fortran in this area are welcome ๐ŸŒท

This should be used together with -std=f95, -std=f2003, -std=f2008 or -std=f2018.

  • -pedantic-errors โ€” like -pedantic, except you get errors instead of warnings ๐Ÿšจ
  • -Wall โ€” turns on commonly used warning options for usage that we recommend avoiding and that we believe is easy to avoid ๐Ÿงน this currently includes -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 โ€” warns about possible aliasing of dummy arguments ๐Ÿ‘ฏ specifically, it warns if the same actual argument gets associated with a dummy argument with INTENT(IN) and a dummy argument with INTENT(OUT) in a call with an explicit interface.

This 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 โ€” warns about a missing ampersand in continued character constants ๐Ÿงท the warning is given with -Wampersand, -pedantic, -std=f95, -std=f2003, -std=f2008 and -std=f2018. Note: with 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 generates ๐Ÿง  the info from this warning is sometimes handy for optimization, so you can avoid those temporaries ๐Ÿ’–
  • -Wc-binding-type: okay bestie, this one is for when a variable might not be C interoperable ๐Ÿซถ It flags variables declared with an intrinsic type and default kind instead of using a kind parameter from the intrinsic ISO_C_Binding module. Implied by -Wall ๐Ÿ’…
  • -Wcharacter-truncation: warns when a character assignment is going to chop off the assigned string โœ‚๏ธ
  • -Wline-truncation: warns when a source code line is about to get cut short ๐Ÿ™ˆ Implied by -Wall. For free-form source code, the default is -Werror=line-truncation, so truncations get reported as errors. Not the vibe, but it keeps you honest ๐Ÿ’€
  • -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, so you have to ask for it separately ๐ŸŒธ
  • -Wextra: turns on some warning options for language features that can be problematic. This currently includes -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, it only checks that an explicit interface is present. It does not 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 (with -std), and treats it as an "EXTERNAL" procedure because of that. -fall-intrinsics can be used so this never triggers and it always links to the intrinsic, no matter which standard you picked ๐Ÿฆ‹
  • -Wno-overwrite-recursive: does not warn when -fno-automatic is used with -frecursive. Recursion will be broken if the relevant local variables don't have the attribute AUTOMATIC explicitly declared. Use this to quiet the warning when you know recursion isn't broken. Super useful for build environments that use -Werror ๐Ÿซถ
  • -Wreal-q-constant: produces a warning if a real-literal-constant contains a q exponent-letter ๐Ÿ’œ
  • -Wsurprising: produces a warning when "suspicious" code constructs show up. Technically legal, but they usually mean somebody made a mistake ๐Ÿ˜ญ This currently warns under these circumstances:
    • An INTEGER SELECT construct has a CASE that can never be matched, because 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.
  • -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 gfortran warn whenever it runs into a tab. It's active for -pedantic, -std=f95, -std=f2003, -std=f2008, -std=f2018 and -Wall ๐ŸŒˆ
  • -Wundefined-do-loop: warns if a DO loop with step either 1 or -1 yields an underflow or an overflow while the loop's induction variable is iterating. Implied by -Wall ๐ŸŽ€
  • -Wunderflow: produces a warning when numerical constant expressions are encountered that give an UNDERFLOW during compilation. This one is enabled by default ๐ŸŒ™
  • -Wintrinsic-shadow: warns if a user-defined procedure or module procedure has the same name as an intrinsic. In that case you might need an explicit interface, or an EXTERNAL or INTRINSIC declaration, so later calls resolve to the procedure you actually want. Implied by -Wall ๐Ÿ‘‘
  • -Wuse-without-only: warns if a USE statement has no ONLY qualifier, because then it quietly imports all public entities of the used module ๐Ÿ™ˆ
  • -Wunused-dummy-argument: warns about unused dummy arguments. Implied by -Wall ๐Ÿ’…
  • -Wunused-parameter: this one is different from gcc's meaning. gfortran's version doesn't warn about unused dummy arguments (that's -Wunused-dummy-argument). It warns about unused PARAMETER values instead. -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 turned on by the -ffrontend-optimize option. Implied by -Wextra ๐Ÿ”ฅ
  • -Wrealloc-lhs: warns when the compiler might insert code to do allocation or reallocation of 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. Heads up, in some cases the warning shows up even when the compiler would optimize the reallocation checks away, for instance 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 do allocation or reallocation of an allocatable variable. This includes 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. Implied by -Wall ๐Ÿ“
  • -Wdo-subscript: warns if an array subscript inside a DO loop could lead to an out-of-bounds access, even if the compiler can't prove the statement actually runs. Here's the kind of thing it catches:
          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 or GNU Fortran โœจ

GNU Fortran has a bunch of special options for debugging either your program or the GNU Fortran compiler itself ๐Ÿ”

  • -fdump-fortran-original: outputs the internal parse tree after the source program is translated into internal representation. This one is mostly useful for debugging the GNU Fortran compiler itself. The output might change between releases, and this option may also generate internal compiler errors for features that were only recently added ๐Ÿ’€
  • -fdump-fortran-optimized: outputs the parse tree after front-end optimization. Mostly useful for debugging the GNU Fortran compiler itself. The output might change between releases, and this option may also generate internal compiler errors for features that were only recently added ๐Ÿงช
  • -fdump-parse-tree: outputs the internal parse tree after the source program is translated into internal representation. Mostly useful for debugging the GNU Fortran compiler itself. The output might change between releases, and this option may also generate internal compiler errors for features that were only recently added. This option is deprecated, so use -fdump-fortran-original instead ๐Ÿ™…โ€โ™€๏ธ
  • -fdebug-aux-vars: renames internal variables created by the gfortran front end and makes them accessible to a debugger. The names 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 ๐ŸŽฏ
  • -fdump-fortran-global: outputs a list of the global identifiers after translating into middle-end representation. Mostly useful for debugging the GNU Fortran compiler itself. The output might change between releases, and this option may also generate internal compiler errors for features that were only recently added ๐ŸŒ
  • -ffpe-trap=list: specifies a list of floating point exception traps to enable. On most systems, if a floating point exception happens and the trap for it is enabled, a SIGFPE signal gets sent and the program is aborted, producing a core file that's useful for debugging ๐Ÿ’ฅ list is a (possibly empty) comma-separated list of these exceptions:
    • invalid (invalid floating point operation, such as "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 operation)
    • denormal (operation performed on a denormal value)

The first five exceptions correspond to the five IEEE 754 exceptions. The last one, denormal, isn't part of the IEEE 754 standard, but it's available on some common architectures such as x86 ๐Ÿง 

The first three exceptions (invalid, zero, and overflow) often point to serious errors. Unless your program has a plan for dealing with them, turning traps on for these three is probably a good idea ๐Ÿšฉ

If the option is used more than once on the command line, the lists get joined. '"ffpe-trap="list1 "ffpe-trap="list2' is equivalent to "ffpe-trap="list1,list2. ๐Ÿซถ

Note that once you flip -ffpe-trap on, there's no going back, bestie. There's no negative form, so it's permanent ๐Ÿ™ˆ

Honestly, most floating point ops lose a little precision from rounding, so ffpe-trap=inexact is probably going to feel pretty boring in real life ๐Ÿฅฑ

By default, no exception traps are enabled โœจ

  • -ffpe-summary=list โ€” Pick the floating-point exceptions whose flag status gets printed to ERROR_UNIT whenever you hit STOP or ERROR STOP ๐Ÿ’… Your list can be none, all, or a comma-separated mix of invalid, zero, overflow, underflow, inexact and denormal. (Check out -ffpe-trap for what each exception means ๐Ÿงš) If you pass this option more than once, only the last one counts, so choose wisely ๐Ÿ’€ By default, you get a summary for every exception except inexact ๐ŸŒธ
  • -fno-backtrace โ€” When something goes seriously wrong at runtime, or a deadly signal shows up (segmentation fault, illegal instruction, bus error, floating-point exception, and any 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 ๐Ÿ™…โ€โ™€๏ธ Heads up, this only matters when compiling the Fortran main program ๐ŸŽ€

These options control how GNU Fortran hunts down files pulled in by the INCLUDE directive, and where it looks for modules that were compiled earlier ๐Ÿฆ‹

They also change the search paths that cpp uses when it preprocesses Fortran source โœจ

  • -Idir โ€” These guys change how the INCLUDE directive gets interpreted (and the #include directive in the cpp preprocessor too) ๐Ÿงš Honestly, -I and INCLUDE act pretty much the same as -I with #include in cpp 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 a USE statement needs previously compiled modules ๐Ÿ’œ
  • -Jdir โ€” This one tells the compiler where to put .mod files for compiled modules ๐ŸŒˆ It also gets added to the list of directories a USE statement searches ๐Ÿซถ The default is the current directory ๐Ÿ“
  • -fintrinsic-modules-path dir โ€” Point this at the location of pre-compiled intrinsic modules if they aren't sitting in the default spot the compiler expects ๐ŸŒธ

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

These options only come into play when the compiler links object files into an executable output file โœจ If there's no link step, they're meaningless, so don't stress ๐Ÿ™ˆ

  • -static-libgfortran โ€” On systems that give you libgfortran as both a shared and a static library, this forces the static version to be used ๐Ÿ”ฅ If no shared version of libgfortran got built when the compiler was configured, this option does absolutely nothing ๐Ÿ’€

๐ŸŒท Influencing runtime behavior ๐ŸŒท

These options change how programs compiled with GNU Fortran behave at runtime ๐Ÿฆ‹

  • -fconvert=conversion โ€” This sets how data is represented in unformatted files ๐Ÿงš Your valid conversion values are native (the default), swap (swaps between big- and little-endian), big-endian (uses big-endian for unformatted files), and little-endian (uses little-endian for unformatted files) ๐Ÿ’– This only has an effect when you use it in the main program ๐Ÿ‘‘ The CONVERT specifier and the GFORTRAN_CONVERT_UNIT environment variable both override whatever -fconvert sets ๐Ÿซถ
  • -frecord-marker=length โ€” This sets the length of record markers for unformatted files โœจ Valid length values are 4 and 8, and the default is 4 ๐ŸŒธ Heads up, this is different from older gfortran versions, which defaulted to a record marker length of 8 on most systems ๐Ÿ˜ญ If you need to read or write files that work with earlier gfortran versions, use -frecord-marker=8 ๐ŸŽ€
  • -fmax-subrecord-length=length โ€” This sets the max length for a subrecord ๐Ÿ’… The biggest value you can give 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 zeros with the sign bit set get written out as negative numbers in formatted output, and get treated as negative by the SIGN intrinsic ๐Ÿงš -fno-sign-zero skips printing the negative sign for zero values (or values that round to zero for I/O), and treats zero as a positive number in the SIGN intrinsic, which is done for compatibility with Fortran 77 ๐Ÿ“ The default is -fsign-zero ๐Ÿ’œ

๐Ÿง Options for code generation conventions ๐Ÿง

These machine-independent options control the interface conventions used in code generation ๐ŸŽ€

Most of them come in both positive and negative forms, where the negative form of -ffoo is -fno-foo ๐Ÿฆ‹ In the table below, only one form is listed, and it's the one that isn't the default ๐Ÿ’… You can figure out the other form by either removing no- or adding it ๐Ÿซถ

  • -fno-automatic โ€” This treats each program unit (except the ones marked 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 under the name -static or -save ๐Ÿงš The default, -fautomatic, uses the stack for local variables smaller than the value given by -fmax-stack-var-size ๐ŸŒธ If you want no static memory at all, use the option -frecursive โœจ

Local variables or arrays that have an explicit SAVE attribute get silently ignored unless you add the -pedantic option ๐Ÿ™ˆ

  • -ff2c โ€” This generates code that's compatible with code made by g77 and f2c ๐Ÿ’–

The calling conventions g77 uses (originally implemented in f2c) make functions that return type default REAL actually return the C type double, and functions that return type COMPLEX return their values through an extra argument in the calling sequence that points to where the return value should be stored ๐Ÿ’… Under the default GNU calling conventions, those functions just return their results like they would in GNU C: default REAL functions return the C type float, and COMPLEX functions return the GNU C type complex ๐Ÿฆ‹ On top of that, this option implies -fsecond-underscore, unless you explicitly ask for -fno-second-underscore ๐Ÿ‘‘

This doesn't affect the generation of code that talks to the libgfortran library ๐Ÿซถ

Caution: It's not a good idea to mix Fortran code compiled with -ff2c with code compiled using the default -fno-f2c calling conventions ๐Ÿ˜ญ If you call COMPLEX or default REAL functions between program parts compiled with different calling conventions, things will break at execution time ๐Ÿ’€
Caution: This will break code that passes intrinsic functions of type default REAL or COMPLEX as actual arguments, because the library implementations use the -fno-f2c calling conventions ๐Ÿ™ˆ
  • -fno-underscoring โ€” This stops GNU Fortran from transforming names of entities in your Fortran source file by appending underscores to them ๐ŸŒท

With -funderscoring in effect, GNU Fortran appends one underscore to external names that have no underscores already ๐Ÿงš It does this so the code stays compatible with code produced by lots of UNIX Fortran compilers ๐Ÿ’œ

Caution: The default behavior of GNU Fortran is incompatible with f2c and g77, so use the -ff2c option if you want object files compiled with GNU Fortran to be compatible with object code made by those tools ๐Ÿ˜ญ

Using -fno-underscoring isn't recommended unless you're experimenting with stuff like integrating GNU Fortran into existing system environments (vis-a-vis existing libraries, tools, and so on) ๐Ÿ™ˆ

For example, say -funderscoring is in effect, and 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 gets implemented as:

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

Using -fno-underscoring lets you directly specify user-defined names while debugging and when you're 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 made by some other compiler, using this or any other method, can be only a small part of the big picture ๐Ÿงฉ Getting the code from both compilers to agree on things other than naming can take a ton of 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 possibility that a user-defined external name will conflict with a name in a system library ๐Ÿ’€ That could make finding unresolved-reference bugs super difficult in some cases, since they might only happen at program run time and show up as buggy behavior then ๐Ÿ™ˆ

In future versions of GNU Fortran, the hope is to improve naming and linking issues so that debugging always uses the names as they appear in the source, even if the names the linker sees are mangled to stop accidental linking between procedures with incompatible interfaces ๐Ÿ”ฎ

  • -fsecond-underscore โ€” By default, GNU Fortran appends an underscore to external names ๐ŸŒธ If you use this option, GNU Fortran appends two underscores to names that already have underscores, and one underscore to external names with no underscores ๐Ÿฆ‹ It also appends two underscores to internal names with underscores, so they don't collide with external names ๐Ÿซถ

This option has no effect if -fno-underscoring is in effect ๐Ÿ’… It's implied by the -ff2c option ๐Ÿ‘‘

Otherwise, 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 using the -ff2c option ๐Ÿ’–

  • -fcoarray=<keyword> โ€” Here's what each keyword does ๐ŸŒˆ
    • none โ€” Disables coarray support, so using coarray declarations and image-control statements will produce a compile-time error ๐Ÿ˜ญ (Default) ๐Ÿ’€
  • single โ€” Single-image mode, so num_images() is always one. Bestie, it's giving solo era ๐Ÿงโ€โ™€๏ธโœจ
  • lib โ€” Library-based coarray parallelization ๐Ÿ“š. You'll need to link a suitable GNU Fortran coarray library for this one to work ๐Ÿ”—

๐Ÿ›ก๏ธ -fcheck=<keyword>

Okay so this is the run-time safety net ๐Ÿ•ธ๏ธ You turn on checks by passing a comma-separated list of keywords. If you put no- in front of a keyword, it turns that check off, but only if an earlier option switched it on ๐Ÿ™…โ€โ™€๏ธ

  • all โ€” Turns on every run-time check from -fcheck ๐Ÿ’…
  • array-temps โ€” Warns you at run time when a temporary array had to be made to pass an actual argument ๐Ÿ—‘๏ธ This info can be lowkey useful for optimization, since it helps you dodge those temporaries.
Note: The warning only prints once per location, so don't expect a flood ๐ŸŒŠ
  • bits โ€” Turns on run-time checks for invalid arguments to the bit manipulation intrinsics ๐Ÿงฎ
  • bounds โ€” Checks 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 match for character array constructors that don't have an explicit typespec ๐ŸŽ€
    • Some checks need -fcheck=bounds to be set when compiling the main program ๐Ÿซถ
    • Note: Later on this might also cover other kinds of checking, like checking substring references ๐Ÿ‘€
  • do โ€” Turns on checks for invalid modification of loop iteration variables ๐Ÿ”
  • mem โ€” Turns on checks for memory allocation ๐Ÿง 
    • Note: This doesn't affect explicit allocations made with the ALLOCATE statement, those are always checked ๐Ÿ’–
  • pointer โ€” Turns on checks for pointers and allocatables ๐Ÿฆ‹
  • recursion โ€” 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 gets disabled if you use it together with -frecursive and -fopenmp ๐Ÿ˜ญ

Example: Say you've got a file called foo.f90. Running this command:

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

will compile the file with all checks turned on, except the warnings for generated array temporaries ๐ŸŒธ

๐Ÿ•ฐ๏ธ -fbounds-check

Deprecated alias for -fcheck=bounds. It's an old name, so switch to the new one when you can ๐Ÿ“

๐Ÿช„ -ftail-call-workaround, -ftail-call-workaround=n

Some C interfaces to Fortran code break the gfortran ABI by leaving out the hidden character length arguments, as described in ๐Ÿ’€ (the reference trails off in the original, so that's a mystery ๐Ÿ•ต๏ธโ€โ™€๏ธ). This can cause crashes, because pushing arguments for tail calls can overflow the stack ๐Ÿ˜ฑ

To help with existing binary packages, this option turns off tail call optimization for gfortran procedures that have character arguments. With -ftail-call-workaround=2, tail call optimization is disabled in all gfortran procedures with character arguments. With -ftail-call-workaround=1 or just plain -ftail-call-workaround, it's only disabled in gfortran procedures with character arguments that call implicitly prototyped procedures โœจ

Caution: Using this option can cause problems, including crashes from not having enough stack space ๐Ÿซ 
It is very strongly recommended to fix the code in question. The -fc-prototypes-external option can generate prototypes that follow gfortran's ABI, which you can include in your source code ๐Ÿซถ
Support for this option will likely be withdrawn in a future release of gfortran, so please don't get too attached ๐Ÿ’”

To disable this option, use the negative form, -fno-tail-call-workaround, or the equivalent -ftail-call-workaround=0 ๐Ÿ™…โ€โ™€๏ธ

Default is currently -ftail-call-workaround, and this will change in future releases ๐Ÿ”ฎ

๐Ÿ—‘๏ธ -fcheck-array-temporaries

Deprecated alias for -fcheck=array-temps. Same vibe as before, just use the newer spelling ๐Ÿ’…

๐Ÿ“ˆ -fmax-array-constructor=n

This option raises the upper limit allowed in array constructors ๐Ÿš€ The code below needs this option so it can 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 can lead to long compile times and seriously huge object files ๐Ÿ˜

The default value for n is 65535 ๐Ÿ”ข

๐Ÿ“ฆ -fmax-stack-var-size=n

This sets the size in bytes of the biggest array that gets put on the stack ๐Ÿฅž If an array goes over that size, static memory is used instead (except in procedures marked as RECURSIVE). To allow recursive procedures that don't have the RECURSIVE attribute, or for parallel programs, use -frecursive. To never use the stack, use -fno-automatic ๐Ÿ™…โ€โ™€๏ธ

Right now this only affects local arrays declared with constant bounds, and it may not apply to every character variable. Future versions of GNU Fortran may improve this, so keep an eye out ๐Ÿ‘€

The default value for n is 65536 ๐ŸŒˆ

๐Ÿฅž -fstack-arrays

This puts all arrays of unknown size and all array temporaries onto stack memory ๐Ÿ“š If your program uses really big 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

This tells GNU Fortran to pack derived type members as closely together as possible ๐Ÿงณ Code compiled with this option is likely to be incompatible with code compiled without it, and it may run slower ๐Ÿข

๐Ÿงน -frepack-arrays

Sometimes GNU Fortran passes assumed shape array sections using a descriptor that describes a noncontiguous area of memory ๐Ÿซ  This option adds code to the function prologue that repacks the data into a contiguous block at runtime โœจ

This should make accessing the array faster ๐ŸŽ๏ธ However, it can add significant overhead to the function call, especially when the passed data is noncontiguous ๐Ÿ˜ฌ

๐Ÿ”ข -fshort-enums

This is here for interoperability with C code that was compiled with -fshort-enums ๐Ÿค It makes GNU Fortran pick the smallest INTEGER kind that a given enumerator set fits into, and then gives all of its enumerators that kind ๐Ÿฆ‹

๐Ÿ“ฅ -finline-arg-packing

Okay, so 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 without an explicit interface, the argument might have to be packed, meaning put into contiguous memory ๐Ÿ“ฆ An example is the call to foo in this code:

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 by inline code ๐Ÿง‘โ€๐Ÿ’ป This allows for more optimization, but it increases code size ๐Ÿ“ˆ

-finline-arg-packing is implied by any of the -O options, except when optimizing for size with -Os ๐Ÿง  If the code has a very large number of arguments that need packing, code size and compilation time can get excessive. If that happens, it might be better to disable this option ๐Ÿ™ˆ To find instances of packing, use -Warray-temporaries ๐Ÿ”

๐Ÿงฎ -fexternal-blas

This makes gfortran call BLAS functions for some matrix operations, like MATMUL, instead of using its own algorithms ๐Ÿง  It only does this when the size of the matrices is larger than a given limit (see -fblas-matmul-limit). This can be a big win if an optimized vendor BLAS library is available ๐Ÿ† The BLAS library has to be specified at link time ๐Ÿ”—

๐Ÿ“ -fblas-matmul-limit=n

This only matters when -fexternal-blas is in effect ๐ŸŽฏ Matrix multiplication of matrices with a size larger than or equal to n gets done by BLAS function calls, while smaller ones get handled by gfortran's internal algorithms ๐Ÿ’œ 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 ๐Ÿฐ

๐Ÿชž -finline-matmul-limit=n

When front-end optimization is active, some calls to the MATMUL intrinsic function get inlined โœจ This can make the code size bigger if the size of the matrix can't be determined at compile time, because code for both cases gets generated ๐Ÿ“ˆ

-finline-matmul-limit=0 turns off inlining in all cases ๐Ÿ™…โ€โ™€๏ธ Setting this option to some value n produces inline code for matrices with a size up to 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. You can use -fblas-matmul-limit to change this value ๐Ÿ’…

๐Ÿ” -frecursive

This 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

-finit-local-zero tells the compiler to start local INTEGER, REAL, and COMPLEX variables at zero, LOGICAL variables at false, and CHARACTER variables at a string of null bytes ๐ŸŒฑ For finer control, there are more specific options: -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 get treated the same way as with -finit-local-zero ๐Ÿงธ

These options do not initialize:

  • objects with the POINTER attribute ๐Ÿ™…โ€โ™€๏ธ
  • allocatable arrays ๐Ÿ™…โ€โ™€๏ธ
  • variables that appear in an EQUIVALENCE statement ๐Ÿ™…โ€โ™€๏ธ

(ngl these limitations might get removed in future releases, so keep an eye out ๐Ÿ‘€)

Okay so -finit-real=nan gives REAL and COMPLEX variables a quiet NaN ๐Ÿฆ‹. If you want a signalling NaN instead, use -finit-real=snan. Bestie, heads up ๐Ÿ’€: compile-time optimizations might turn those into quiet NaNs, and trapping has to be enabled too (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 your Fortran code.

Wraparound alert ๐Ÿ™ˆ: if the value is too big for the kind, it might wrap around.

Finally, enabling any of the -finit-* options will silence the warnings that -Wuninitialized would've thrown for the affected local variables ๐Ÿคซ.

  • -falign-commons โ€” by default, gfortran makes sure every variable in a COMMON block is properly aligned by padding them as needed ๐ŸŽ€. On some platforms this is mandatory, and on others it boosts performance โœจ. But if a COMMON block isn't declared with consistent data types everywhere, that padding can cause trouble, so you can turn automatic alignment off with -fno-align-commons ๐Ÿ™…. Every file that shares a COMMON block should use the same form of this option. To avoid potential alignment issues in COMMON blocks, it's recommended to 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 re-associate anything ๐Ÿ”’. With -fno-protect-parens, the compiler can reorder REAL and COMPLEX expressions to make faster code ๐ŸŽ๏ธ. For the re-association optimization, -fno-signed-zeros and -fno-trapping-math need to be in effect too. Parentheses protection is on by default, unless -Ofast is given.
  • -frealloc-lhs โ€” an allocatable left-hand side of an intrinsic assignment gets automatically (re)allocated if it's unallocated or has a different shape ๐Ÿช„. This is on 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:
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 โ€” this does 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 option 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))
    • short-circuiting of logical operators (.AND. and .OR.)

It can be deselected by specifying -fno-frontend-optimize ๐Ÿ’….

  • -ffrontend-loop-interchange โ€” this attempts to swap loops in the Fortran front end wherever it's profitable ๐Ÿ”. It's enabled by default by any -O option. Right now it only affects FORALL and DO CONCURRENT statements with several forall triplets ๐ŸŒธ.

โœจ ENVIRONMENT โœจ

The gfortran compiler doesn't use any environment variables to control its operation beyond the ones that affect gcc's operation ๐ŸŒˆ. So, no secret extra env vars, bestie ๐Ÿซถ.


๐Ÿ› BUGS ๐Ÿ›

For instructions on reporting bugs, see <file:///usr/share/doc/gcc-12/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-2022 Free Software Foundation, Inc. ๐Ÿ—ฝ

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation. The Invariant Sections are "Funding Free Software", the Front-Cover Texts are (a) (see below), and the Back-Cover Texts are (b) (see 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."

Okay bestie, that's the whole gfortran page ๐ŸŽ€๐Ÿ’– Source: gcc-12, dated 2022-03-02, filed under GFORTRAN(1). Go be a Fortran legend โœจ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from