Sun Studio 12 Update 1: Fortran User's Guide

Chapter 2 Using Sun Studio Fortran

This chapter describes how to use the Fortran compiler.

The principal use of any compiler is to transform a program written in a procedural language like Fortran into a data file that is executable by the target computer hardware. As part of its job, the compiler may also automatically invoke a system linker to generate the executable file.

The compiler can also be used to:

2.1 A Quick Start

This section provides a quick overview of how to use the Fortran compiler to compile and run Fortran programs. A full reference to command-line options appears in the next chapter.

The very basic steps to running a Fortran application involve using an editor to create a Fortran source file with a .f, .for, .f90, .f95, .F, .F90, or .F95 filename suffix; invoking the compiler to produce an executable; and finally, launching the program into execution by typing the name of the file:

Example: This program displays a message on the screen:

demo% cat greetings.f
      PRINT *, ’Real programmers write Fortran!’
demo% f95 greetings.f
demo% a.out
 Real programmers write Fortran!

In this example, f95 compiles source file greetings.f and links the executable program onto the file, a.out, by default. To launch the program, the name of the executable file, a.out, is typed at the command prompt.

Traditionally, UNIX compilers write executable output to the default file called a.out. It can be awkward to have each compilation write to the same file. Moreover, if such a file already exists, it will be overwritten by the next run of the compiler. Instead, use the -o compiler option to explicitly specify the name of the executable output file:

demo% f95 -o greetings greetings.f
demo% greetings
 Real programmers write Fortran!

In the preceding example, the -o option tells the compiler to write the executable code to the file greetings. (By convention, executable files usually are given the same name as the main source file, but without an extension.)

Alternatively, the default a.out file could be renamed via the mv command after each compilation. Either way, run the program by typing the name of the executable file at a shell prompt.

The next sections of this chapter discuss the conventions used by the f95 commands, compiler source line directives, and other issues concerning the use of these compiler. The next chapter describes the command-line syntax and all the options in detail.

2.2 Invoking the Compiler

The syntax of a simple compiler command invoked at a shell prompt is:

f95 [options] files...

Here files… is one or more Fortran source file names ending in .f, .F, .f90, .f95, .F90, .F95, or .for; options is one or more of the compiler option flags. (Files with names ending in a .f90 or .f95 extension are “free-format” Fortran 95 source files recognized only by the f95 compiler.)

In the example below, f95 is used to compile two source files to produce an executable file named growth with runtime debugging enabled:

demo% f95 -g -o growth growth.f fft.f95

Note –

You can invoke the Fortran compiler with either the f95 or f90 command.

New: The compiler will also accept source files with the extension .f03 or .F03. These are treated as equivalent to .f95 and .F95 and could be used as a way to indicate that a source file contains Fortran 2003 extensions.

2.2.2 Command-Line File Name Conventions, describes the various source file extensions accepted by the compiler.

2.2.1 Compile-Link Sequence

In the previous example, the compiler automatically generates the loader object files, growth.o and fft.o, and then invokes the system linker to create the executable program file growth.

After compilation, the object files, growth.o and fft.o, will remain. This convention permits easy relinking and recompilation of files.

If the compilation fails, you will receive a message for each error. No .o files are generated for those source files with errors, and no executable program file is written.

2.2.2 Command-Line File Name Conventions

The suffix extension attached to file names appearing on the command-line determine how the compiler will process the file. File names with a suffix extension other than one of those listed below, or without an extension, are passed to the linker.

Table 2–1 Filename Suffixes Recognized by the Fortran Compiler





Fortran 77 or Fortran 95 fixed-format 

Compile Fortran source files, put object files in current directory; default name of object file is that of the source but with .o suffix.


Fortran 95 free-format 

Same action as .f


Fortran 2003 free-format 

Same action as .f


Fortran 77 orFortran 95 

Same action as .f.


Fortran 77 or Fortran 95 fixed-format 

Apply the Fortran (or C) preprocessor to the Fortran 77 source file before compilation. 


Fortran 95 free-format 

Apply the Fortran (or C) preprocessor to the Fortran 95 free-format source file before Fortran compiles it. 


Fortran 2003 free-format 

Same as .F95



Assemble source files with the assembler. 



Apply the C preprocessor to the assembler source file before assembling it. 


Inline expansion 

Process template files for inline expansion. The compiler will use templates to expand inline calls to selected routines. (Template files are special assembler files; see the inline(1) man page.)


Object files 

Pass object files through to the linker. 



Pass names of libraries to the linker. .a files are static libraries, .so and .so.n files are dynamic libraries.

Fortran 95 free-format is described in 4.1 Source Language Features.

2.2.3 Source Files

The Fortran compiler will accept multiple source files on the command line. A single source file, also called a compilation unit, may contain any number of procedures (main program, subroutine, function, block data, module, and so on). Applications may be configured with one source code procedure per file, or by gathering procedures that work together into single files. The Fortran Programming Guide describes the advantages and disadvantages of these configurations.

2.2.4 Source File Preprocessors

f95 supports two source file preprocessors, fpp and cpp. Either can be invoked by the compiler to expand source code “macros” and symbolic definitions prior to compilation. The compiler will use fpp by default; the -xpp=cpp option changes the default from fpp to cpp. (See also the discussion of the -Dname option).

fpp is a Fortran-specific source preprocessor. See the fpp(1) man page and the fpp README for details. It is invoked by default on files with a .F, .F90, F95, or .F03 extension.

The source code for fpp is available from the Netlib web site at

See cpp(1) for information on the standard Unix C language preprocessor. Use of fpp over cpp is recommended on Fortran source files.

2.2.5 Separate Compiling and Linking

You can compile and link in separate steps. The -c option compiles source files and generates .o object files, but does not create an executable. Without the -c option the compiler will invoke the linker. By splitting the compile and link steps in this manner, a complete recompilation is not needed just to fix one file, as shown in the following example:

Compile one file and link with others in separate steps:

demo% f95 -c file1.f                          (Make new object file)
demo% f95 -o prgrm file1.o file2.o file3.o         (Make executable file)

Be sure that the link step lists all the object files needed to make the complete program. If any object files are missing from this step, the link will fail with undefined external reference errors (missing routines).

2.2.6 Consistent Compiling and Linking

Ensuring a consistent choice of compiling and linking options is critical whenever compilation and linking are done in separate steps. Compiling any part of a program with some options requires linking with the same options. Also, a number of options require that all source files be compiled with that option, including the link step.

The option descriptions in Chapter 3 identify such options.

Example: Compiling sbr.f with -fast, compiling a C routine, and then linking in a separate step:

demo% f95 -c -fast sbr.f
demo% cc -c -fast simm.c
demo% f95 -fast sbr.o simm.o        link step; passes  -fast  to the linker

2.2.7 Unrecognized Command-Line Arguments

Any arguments on the command-line that the compiler does not recognize are interpreted as being possibly linker options, object program file names, or library names.

The basic distinctions are:

For example:

demo% f95 -bit move.f           <-  -bit is not a recognized f95 option
f95: Warning: Option -bit passed to ld, if ld is invoked, ignored otherwise
demo% f95 fast move.f           <-   The user meant to type -fast
ld: fatal: file fast: cannot open file; errno=2
ld: fatal: File processing errors.  No output written to a.out

Note that in the first example, -bit is not recognized by f95 and the option is passed on to the linker (ld), who tries to interpret it. Because single letter ld options may be strung together, the linker sees -bit as -b -i -t, which are all legitimate ld options! This may (or may not) be what the user expects, or intended.

In the second example, the user intended to type the f95 option -fast but neglected the leading dash. The compiler again passes the argument to the linker which, in turn, interprets it as a file name.

These examples indicate that extreme care should be observed when composing compiler command lines!

2.2.8 Modules

f95 automatically creates module information files for each MODULE declaration encountered in the source files, and searches for modules referenced by a USE statement. For each module encountered (MODULE module_name), the compiler generates a corresponding file, module_name.mod, in the current directory. For example, f95 generates the module information file list.mod for the MODULE list unit found on file mysrc.f95 .

See the -Mpath and -moddir dirlist option flags for information on how to set the defaults paths for writing and searching for module information files.

See also the -use compiler option for implicitly invoking MODULE declarations in all compilation units.

Use the fdumpmod(1) command to display information about the contents of a .mod module information file.

For detailed information, see 4.9 Module Files.

2.3 Directives

Use a source code directive, a form of Fortran comment, to pass specific information to the compiler regarding special optimization or parallelization choices. Compiler directives are also sometimes called pragmas. The compiler recognize a set of general directives and parallelization directives. f95 also processes OpenMP shared memory multiprocessing directives.

Directives unique to f95 are described in 4.8 Directives. A complete summary of all the directives recognized by f95 appears in Table C–1.

Note –

Directives are not part of the Fortran standard.

2.3.1 General Directives

The various forms of a general Fortran directive are:

C$PRAGMA keyword ( a [ , a ] ) [ , keyword ( a [ , a ] ) ] ,

C$PRAGMA SUN keyword ( a [ , a ] … ) [ , keyword ( a [ , a ] … ) ] ,…

C$PRAGMA SPARC keyword ( a [ , a ] … ) [ , keyword ( a [ , a ] … ) ] ,…

The variable keyword identifies the specific directive. Additional arguments or suboptions may also be allowed. (Some directives require the additional keyword SUN or SPARC, as shown above.)

A general directive has the following syntax:

Observe the following restrictions:

The Fortran compiler recognize the following general directives:

Table 2–2 Summary of General Fortran Directives

C Directive

C$PRAGMA C(list)

Declares a list of names of external functions as C language routines. 

IGNORE_TKR Directive

C$PRAGMA IGNORE_TKR {name {, name} ...}

The compiler ignores the type, kind, and rank of the specified dummy argument names appearing in a generic procedure interface when resolving a specific call. 

UNROLL Directive


Advises the compiler that the following loop can be unrolled to a length n.

WEAK Directive

C$PRAGMA WEAK(name[=name2])

Declares name to be a weak symbol, or an alias for name2.

OPT Directive


Set optimization level for a subprogram to n.

PIPELOOP Directive


Assert dependency in the following loop exists between iterations n apart.

PREFETCH Directives


Request compiler generate prefetch instructions for references to name. (Requires -xprefetch option, which is enabled by default. Prefetch directives can be disabled by compiling with —xprefetch=no. Target architecture must also support prefetch instructions, and the compiler optimization level must be greater than —xO2.)

ASSUME Directives

C$PRAGMA [BEGIN} ASSUME (expression [,probability])


Make assertions about conditions at certain points in the program that the compiler can assume are true. The C Directive

The C() directive specifies that its arguments are external functions.It is equivalent to an EXTERNAL declaration except that unlike ordinary external names, the Fortran compiler will not append an underscore to these argument names. See the C-Fortran Interface chapter in the Fortran Programming Guide for more details.

The C() directive for a particular function should appear before the first reference to that function in each subprogram that contains such a reference.

Example - compiling ABC and XYZ for C:


This directive causes the compiler to ignore the type, kind, and rank of the specified dummy argument names appearing in a generic procedure interface when resolving a specific call.

For example, in the procedure interface below, the directive specifies that SRC can be any data type, but LEN can be either KIND=4 or KIND=8.The interface block defines two specific procedures for a generic procedure name.This example is shown in Fortran 95 free format.





The subroutine call:

REAL S(100)

The call to BLCKX will call BLCK_32 when compiled normally, and BLCK_64 when compiled with -xtypemap=integer:64. The actual type of S does not determine which routine to call. This greatly simplifies writing generic interfaces for wrappers that call specific library routines based on argument type, kind, or rank.

Note that dummy arguments for assumed-shape arrays, Fortran pointers, or allocatable arrays cannot be specified on the directive. If no names are specified, the directive applies to all dummy arguments to the procedure, except dummy arguments that are assumed-shape arrays, Fortran pointers, or allocatable arrays. The UNROLL Directive

The UNROLL directive requires that you specify SUN after C$PRAGMA.

The C$PRAGMA SUN UNROLL=n directive instructs the compiler to unroll the following loop n times during its optimization pass. (The compiler will unroll a loop only when its analysis regards such unrolling as appropriate.)

n is a positive integer. The choices are:

If any loops are actually unrolled, the executable file becomes larger. For further information, see the Fortran Programming Guide chapter on performance and optimization.

Example - unrolling loops two times:


The WEAK directive defines a symbol to have less precedence than an earlier definition of the same symbol. This pragma is used mainly in sources files for building libraries. The linker does not produce an error message if it is unable to resolve a weak symbol.

C$PRAGMA WEAK (name1 [=name2])

WEAK (name1) defines name1 to be a weak symbol. The linker does not produce an error message if it does not find a definition for name1.

WEAK (name1=name2) defines name1 to be a weak symbol and an alias for name2.

If your program calls but does not define name1, the linker uses the definition from the library. However, if your program defines its own version of name1, then the program’s definition is used and the weak global definition of name1 in the library is not used. If the program directly calls name2, the definition from library is used; a duplicate definition of name2 causes an error. See the Solaris Linker and Libraries Guide for more information. The OPT Directive

The OPT directive requires that you specify SUN after C$PRAGMA.

The OPT directive sets the optimization level for a subprogram, overriding the level specified on the compilation command line. The directive must appear immediately before the target subprogram, and only applies to that subprogram. For example:

        SUBROUTINE smart(a,b,c,d,e)

When the above is compiled with an f95 command that specifies -O4, the directive will override this level and compile the subroutine at -O2. Unless there is another directive following this routine, the next subprogram will be compiled at -O4.

The routine must also be compiled with the -xmaxopt[=n] option for the directive to be recognized. This compiler option specifies a maximum optimization value for PRAGMA OPT directives: if a PRAGMA OPT specifies an optimization level greater than the -xmaxopt level, the -xmaxopt level is used. The PIPELOOP[=n] Directive

The PIPELOOP=n directive requires that you specify SUN after C$PRAGMA.

This directive must appear immediately before a DO loop. n is a positive integer constant, or zero, and asserts to the optimizer a dependence between loop iterations. A value of zero indicates that the loop has no inter-iteration (loop-carried) dependencies and can be freely pipelined by the optimizer. A positive n value implies that the I-th iteration of the loop has a dependency on the (I-n)-th iteration, and can be pipelined at best for only n iterations at a time. (Default if n is not specified is 0)

C    We know that the value of K is such that there can be no
C    cross-iteration dependencies (E.g. K>N)
      DO I=1,N
       A(I)=A(I+K) + D(I)
       B(I)=B(I) + A(I)
      END DO

For more information on optimization, see the Fortran Programming Guide. The PREFETCH Directives

The -xprefetch option flag, 3.4.157 –xprefetch[=a[,a]], enables a set of PREFETCH directives that advise the compiler to generate prefetch instructions for the specified data element on processors that support prefetch.


See also the C User’s Guide, or the SPARC Architecture Manual, Version 9 for further information about prefetch instructions. The ASSUME Directives

The ASSUME directive gives the compiler hints about conditions at certain points in the program. These assertions can help the compiler to guide its optimization strategies. The programmer can also use these directives to check the validity of the program during execution. There are two formats for ASSUME.

The syntax of the “point assertion” ASSUME is

C$PRAGMA ASSUME (expression [,probability])

Alternatively, the “range assertion” ASSUME is:

C$PRAGMA BEGIN ASSUME [expression [, probability)
     block of statements

Use the point assertion form to state a condition that the compiler can assume at that point in the program. Use the range assertion form to state a condition that holds over the enclosed range of statements. The BEGIN and END pairs in a range assertion must be properly nested.

The required expression is a boolean expression that can be evaluated at that point in the program that does not involve user-defined operators or function calls except for those listed below.

The optional probability value is a real number from 0.0 to 1.0, or an integer 0 or 1, giving the probability of the expression being true. A probability of 0.0 (or 0) means never true, and 1.0 (or 1) means always true. If not specified, the expression is considered to be true with a high probability, but not a certainty. An assertion with a probability other than exactly 0 or 1 is a non-certain assertion. Similarly, an assertion with a probability expressed exactly as 0 or 1 is a certain assertion.

For example, if the programmer knows that the length of a DO loop is always greater than 10,000, giving this hint to the compiler can enable it to produce better code. The following loop will generally run faster with the ASSUME pragma than without it.

C$PRAGMA BEGIN ASSUME(__tripcount().GE.10000,1) !! a big loop
        do i = j, n
           a(i) = a(j) + 1
        end do

Two intrinsic functions are available for use specifically in the expression clause of the ASSUME directive. (Note that their names are prefixed by two underscores.)


Use in point assertions placed immediately before a branching statement with a boolean controlling expression. It yields the same result as the boolean expression controlling the branching statement. 


Yields the trip count of the loop immediately following or enclosed by the directive. When used in a point assertion, the statement following the directive must be the first line of a DO. When used in a range assertion, it applies to the outermost enclosed loop.

This list of special intrinsics might expand in future releases.

Use with the -xassume_control compiler option. (See 3.4.111 –xassume_control[=keywords]) For example, when compiled with -xassume_control=check, the example above would produce a warning if the trip count ever became less than 10,000.

Compiling with -xassume_control=retrospective will generate a summary report at program termination of the truth or falsity of all assertions. See the f95 man page for details on -xassume_control.

Another example:

C$PRAGMA ASSUME(__tripcount.GT.0,1)
       do i=n0, nx

Compiling the above example with -xassume_control=check will issue a runtime warning should the loop not be taken because the trip count is zero or negative.

2.3.2 Parallelization Directives

Parallelization directives explicitly request the compiler to attempt to parallelize the DO loop or the region of code that follows the directive. The syntax differs from general directives. Parallelization directives are only recognized when compiling with -openmp. Details regarding Fortran parallelization can be found in the OpenMP API User’s Guide and the Fortran Programming Guide.

The Fortran compiler supports the OpenMP 3.0 shared memory parallelization model. Legacy Sun and Cray parallelization directives are now deprecated and should not be used. OpenMP Parallelization Directives

The Fortran compiler recognizes the OpenMP Fortran shared memory multiprocessing API as the preferred parallel programming model. The API is specified by the OpenMP Architecture Review Board (

You must compile with the command-line option -xopenmp, to enable OpenMP directives. (see 3.4.149 –xopenmp[={parallel|noopt|none}].)

For more information about the OpenMP directives accepted by f95, see the OpenMP API User’s Guide. Legacy Sun/Cray Parallelization Directives

Note –

Legacy Sun and Cray style parallelization directives are now deprecated. The OpenMP parallelization API is preferred. Information on how to migrate from legacy Sun/Cray directives to the OpenMP model appears in the OpenMP API User’s Guide.

2.4 Library Interfaces and

The Fortran compiler provides an include file,, that defines the interfaces for most non-intrinsic library routines. Declare this include file to insure that functions you call and their arguments are properly typed, especially when default data types are changed with -xtypemap.

For example, the following may produce an arithmetic exception because function getpid() is not explicitly typed:

        integer(4) mypid
        mypid = getpid()
        print *, mypid

The getpid() routine returns an integer value but the compiler assumes it returns a real value if no explicit type is declared for the function. This value is further converted to integer, most likely producing a floating-point error.

To correct this you should explicitly type getuid() and functions like it that you call:

        integer(4) mypid, getpid
        mypid = getpid()
        print *, mypid

Problems like these can be diagnosed with the -Xlist (global program checking) option. The Fortran include file ”’ provides explicit interface definitions for these routines.

        include ’’
        integer(4) mypid
        mypid = getpid()
        print *, mypid

Including in program units calling routines in the Fortran library will automatically define the interfaces for you, and help the compiler diagnose type mismatches. (See the Fortran Library Reference for more information.)

2.5 Compiler Usage Tips

The next sections suggest a number of ways to use the Fortran compiler efficiently. A complete compiler options reference follows in the next chapter.

2.5.1 Determining Hardware Platform

Some compiler flags allow the user to tune code generation to a specific set of hardware platform options. The compiler’s -dryrun option can be used to determine the native processor:

<sparc>%f95 -dryrun -xtarget=native
###     command line files and options (expanded):
### -dryrun -xarch=v8plusb -xcache=64/32/4:1024/64/4 -xchip=ultra3i

<x64>%f95 -dryrun -xtarget=native
###     command line files and options (expanded):
### -dryrun -xarch=sse2a -xcache=64/64/2:1024/64/16 -xchip=opteron

2.5.2 Using Environment Variables

You can specify options by setting the FFLAGS or OPTIONS variables.

Either FFLAGS or OPTIONS can be used explicitly in the command line. When you are using the implicit compilation rules of make, FFLAGS is used automatically by the make program.

Example: Set FFLAGS: (C Shell)

demo% setenv FFLAGS ’-fast -Xlist’

Example: Use FFLAGS explicitly:

demo% f95 $FFLAGS any.f

When using make, if the FFLAGS variable is set as above and the makefile’s compilation rules are implicit, that is, there is no explicit compiler command line, then invoking make will result in a compilation equivalent to:

f95 -fast -Xlist files

make is a very powerful program development tool that can easily be used with all Sun compilers. See the make(1) man page and the Program Development chapter in the Fortran Programming Guide.

Note –

Default implicit rules assumed by make may not recognize files with extensions .f95 and .mod (Module files). See the Fortran Programming Guide and the Fortran readme file for details.

2.5.3 Memory Size

A compilation may need to use a lot of memory. This will depend on the optimization level chosen and the size and complexity of the files being compiled. On SPARC platforms, if the optimizer runs out of memory, it tries to recover by retrying the current procedure at a lower level of optimization and resumes subsequent routines at the original level specified in the -On option on the command line.

A processor running the compiler should have at least 64 megabytes of memory; 256 megabytes are recommended. Enough swap space should also be allocated. 200 megabytes is the minimum; 300 megabytes is recommended.

Memory usage depends on the size of each procedure, the level of optimization, the limits set for virtual memory, the size of the disk swap file, and various other parameters.

Compiling a single source file containing many routines could cause the compiler to run out of memory or swap space.

If the compiler runs out of memory, try reducing the level of optimization, or split multiple-routine source files into files with one routine per file, using fsplit(1). Swap Space Limits

The SunOSTM operating system command, swap -s, displays available swap space. See swap(1M).

Example: Use the swap command:

demo% swap -s
total: 40236k bytes allocated + 7280k reserved = 47516k used, 1058708k available
To determine the actual real memory:

demo% /usr/sbin/dmesg | grep mem
mem = 655360K (0x28000000)
avail mem = 602476544 Increasing Swap Space

Use mkfile(1M) and swap(1M) to increase the size of the swap space on a workstation. You must become superuser to do this. mkfile creates a file of a specific size, and swap -a adds the file to the system swap space:

demo# mkfile -v 90m /home/swapfile
/home/swapfile 94317840 bytes
demo# /usr/sbin/swap -a  /home/swapfile Control of Virtual Memory

Compiling very large routines (thousands of lines of code in a single procedure) at optimization level -O3 or higher may require additional memory that could degrade compile-time performance. You can control this by limiting the amount of virtual memory available to a single process.

In a sh shell, use the ulimit command. See sh(1).

Example: Limit virtual memory to 16 Mbytes:

demo$ ulimit -d 16000

In a csh shell, use the limit command. See csh(1).

Example: Limit virtual memory to 16 Mbytes:

demo% limit datasize 16M

Each of these command lines causes the optimizer to try to recover at 16 Mbytes of data space.

This limit cannot be greater than the system’s total available swap space and, in practice, must be small enough to permit normal use of the system while a large compilation is in progress. Be sure that no compilation consumes more than half the space.

Example: With 32 Mbytes of swap space, use the following commands:

In a sh shell:

demo$ ulimit -d 1600

In a csh shell:

demo% limit datasize 16M

The best setting depends on the degree of optimization requested and the amount of real and virtual memory available.

In 64-bit Solaris environments, the soft limit for the size of an application data segment is 2 Gbytes. If your application needs to allocate more space, use the shell’s limit or ulimit command to remove the limit.

For csh use:

demo% limit datasize unlimited

For sh or ksh, use:

demo$ ulimit -d unlimited

See the Solaris 64-bit Developer’s Guide for more information.