ZetCode

Fortran variables and declarations

last modified November 14, 2026

A variable is a named storage location with a type. This article shows how variables are declared in Fortran, how names are written, why implicit none is part of every program, how constants are declared, how initial values behave in procedures, and where a variable is visible.

Declaring variables

A declaration has the form type :: name. The double colon is optional in the simplest case, but it is required when the declaration has attributes or an initial value, so it is good practice to always write it. Several names of the same type can share one declaration, and a name may be given a value right where it is declared.

declarations.f90
program declarations
    implicit none
    integer :: age
    real :: height, weight
    logical :: is_student
    character(len=20) :: name
    integer :: x = 10, y = 20

    age = 28
    height = 1.82
    weight = 74.5
    is_student = .true.
    name = 'Alice'

    print *, 'Name:   ', name
    print *, 'Age:    ', age
    print *, 'Height: ', height
    print *, 'Weight: ', weight
    print *, 'Student:', is_student
    print *, 'x + y = ', x + y
end program declarations

The program declares an integer, two reals, a logical, a character variable that holds up to 20 characters, and two integers with initial values. The assignments use a single equals sign, and a logical value is written .true. or .false.. Real values print with all the digits of their single-precision representation, which is why 1.82 appears as 1.82000005; the data types article explains this. A character variable is padded with blanks to its declared length, so the name is printed followed by trailing spaces.

$ gfortran declarations.f90 -o declarations
$ ./declarations
 Name:   Alice
 Age:              28
 Height:    1.82000005
 Weight:    74.5000000
 Student: T
 x + y =           30

Names

A name consists of letters, digits, and underscores, and it must start with a letter. It may have up to 63 characters. Names are case-insensitive, so Total_Count and total_count denote the same variable. The usual style is lower case with underscores between words.

names.f90
program names
    implicit none
    integer :: Total_Count, total_count_2
    integer :: the_longest_legal_name_has_exactly_sixty_three_characters_in_it

    total_count = 1
    TOTAL_COUNT_2 = 2
    the_longest_legal_name_has_exactly_sixty_three_characters_in_it = 3

    print *, Total_Count + total_count_2 + &
             the_longest_legal_name_has_exactly_sixty_three_characters_in_it
    print *, len('the_longest_legal_name_has_exactly_sixty_three_characters_in_it')
end program names

The program declares one variable with a mixed-case name and uses it with different casing, and it declares a name with exactly 63 characters, the longest the standard guarantees. A name with 64 characters is rejected by gfortran with the error Name at (1) is too long. The last statement prints the length of the name, written as a character literal, to confirm the count.

$ gfortran names.f90 -o names
$ ./names
           6
          63

Assignment

The equals sign in Fortran is the assignment operator, not a comparison; the comparison operator is ==. An assignment copies the value of the right-hand side into the variable on the left, converting the type when necessary. Exchanging two values needs a third variable, because the language has no tuple assignment.

swap.f90
program swap
    implicit none
    integer :: a, b, tmp

    a = 3
    b = 8
    tmp = a
    a = b
    b = tmp
    print *, 'a =', a, ' b =', b
end program swap

The program stores the first value in tmp, overwrites a with b, and finally copies the saved value into b. After the three assignments the two variables have exchanged their values.

$ gfortran swap.f90 -o swap
$ ./swap
 a =           8  b =           3

Implicit typing

Early Fortran did not require declarations. A variable that was not declared received its type from the first letter of its name: names starting with i to n were integers and every other name was real. The rule is one reason for the habit of using i, j and k for loop counters. It is still active in every program unit that lacks implicit none, and it hides mistakes.

implicit.f90
program implicit_typing
    total = 10.5
    count = 3
    average = total / count
    print *, 'Average:', average
    print *, 'Type of count:', count
    print *, 'Typo:', totl
end program implicit_typing

None of the three variables is declared. The names total, count and average start with t, c and a, which are outside the range i to n, so all three are real; the integer value 3 is silently stored as 3.0. The typo totl in the last line is worse: the compiler treats it as a new real variable that was never assigned, and the program prints whatever value that storage holds, here zero. The compiler was run with the strict options of this series and still produced no warning at all.

$ gfortran implicit.f90 -o implicit
$ ./implicit
 Average:   3.50000000
 Type of count:   3.00000000
 Typo:   0.00000000

The implicit none statement

The statement implicit none switches implicit typing off for the program unit, and every name must then be declared. It is written directly after the use statements and before any declaration. A module that has it protects its procedures too, because they inherit the setting from the module.

implicitnone.f90
program implicit_none_demo
    implicit none
    real :: total, average
    integer :: count

    total = 10.5
    count = 3
    average = totl / count
    print *, 'Average:', average
end program implicit_none_demo

The program is the same calculation with implicit none and the same typo, totl. This time the compiler refuses to build it, names the unknown symbol, and even suggests the variable that was probably meant. A mistake that was silent in the previous program is now found before the program runs.

$ gfortran implicitnone.f90 -o implicitnone
implicitnone.f90:8:18:

    8 |     average = totl / count
      |                  1
Error: Symbol ‘totl’ at (1) has no IMPLICIT type; did you mean ‘total’?

Named constants

The parameter attribute declares a named constant. Its value is fixed at compile time, it must be given in the declaration, and it can be used anywhere a constant expression is allowed, for example in array bounds. An attempt to change it is a compile-time error rather than a run-time surprise.

param.f90
program param
    implicit none
    real, parameter :: pi = 3.14159265
    integer, parameter :: max_items = 100

    print *, 'pi =', pi
    print *, 'max =', max_items
    pi = 3.0
end program param

The program declares a real and an integer constant and prints them, and then tries to assign to pi. The compiler rejects the assignment and tells us that a named constant cannot be on the left of one. Constants are covered further in the literals and constants article.

$ gfortran param.f90 -o param
param.f90:8:4:

    8 |     pi = 3.0
      |    1
Error: Named constant ‘pi’ in variable definition context (assignment) at (1)

Initial values and the save attribute

A variable with an initial value in its declaration is initialised only once, when the program starts, and not every time the procedure is called. Fortran gives such a variable the save attribute automatically, so it keeps its value between calls. This is a frequent source of surprises for programmers who know languages in which an initialiser runs on every entry.

initsave.f90
program initsave
    implicit none
    integer :: i

    do i = 1, 3
        call counter()
    end do

contains

    subroutine counter()
        integer :: calls = 0
        integer :: fresh

        fresh = 0
        calls = calls + 1
        fresh = fresh + 1
        print *, 'calls =', calls, ' fresh =', fresh
    end subroutine counter
end program initsave

The subroutine counter has two local variables. calls has an initial value, so it is initialised once and then keeps counting. fresh has no initial value and is set to zero by an assignment on every call, so it is always 1 after the increment. If you need a variable that starts fresh on each call, declare it without an initial value and assign it in the executable part.

$ gfortran initsave.f90 -o initsave
$ ./initsave
 calls =           1  fresh =           1
 calls =           2  fresh =           1
 calls =           3  fresh =           1

Scope

A variable is visible in the program unit that declares it and in the internal procedures that follow contains. This is called host association: an internal procedure can read and change the variables of its host, unless it declares a variable of the same name. The block construct opens a nested scope in which new variables can be declared; they exist only until end block.

scope.f90
program scope
    implicit none
    integer :: x = 1

    print *, 'main, before:', x
    call inner()
    print *, 'main, after: ', x

    block
        integer :: x
        x = 99
        print *, 'block:       ', x
    end block
    print *, 'main, end:   ', x

contains

    subroutine inner()
        integer :: y
        y = x + 100
        x = x + 1
        print *, 'inner:       ', y
    end subroutine inner
end program scope

The subroutine inner reads x from the main program and increments it, so the main program sees the value 2 afterwards. The variable y is local to the subroutine. The block declares its own x, which hides the outer one: the assignment of 99 changes only the inner variable, and the outer x is still 2 after the block.

$ gfortran scope.f90 -o scope
$ ./scope
 main, before:           1
 inner:                101
 main, after:            2
 block:                 99
 main, end:              2

Uninitialised variables

A variable that has neither an initial value nor an assignment holds an undefined value. Reading it is an error in the program, but the compiler is not required to detect it. The warning options of gfortran find many such cases, though not all of them.

uninit.f90
program uninit
    implicit none
    integer :: n
    integer :: total

    total = total + n
    print *, total
end program uninit

Both total and n are read before they are assigned. With -Wall the compiler reports both variables and shows where they were declared. The program still compiles and runs, and the printed number is whatever happened to be in memory; it is different on another machine or after a different compilation. Treat every such warning as a bug.

$ gfortran -Wall uninit.f90 -o uninit
uninit.f90:6:21:

    6 |     total = total + n
      |                     ^
Warning: ‘total’ is used uninitialized [-Wuninitialized]
uninit.f90:4:20:

    4 |     integer :: total
      |                    ^
note: ‘total’ declared here
uninit.f90:6:21:

    6 |     total = total + n
      |                     ^
Warning: ‘n’ is used uninitialized [-Wuninitialized]
uninit.f90:3:16:

    3 |     integer :: n
      |                ^
note: ‘n’ was declared here
$ ./uninit
 -1465998685

Next steps

The data types and kinds article describes the types that a declaration can name and the precision of numbers, and the literals and constants article shows how values are written in the source. For the layout of a whole program, see Fortran program structure.

Source

GNU Fortran: Options to request or suppress errors and warnings

Fortran 2018 standard (J3/18-007r1)

Fortran-lang: learn Fortran

In this article we have declared variables, looked at the rules for names, seen what implicit typing does and why implicit none prevents it, declared named constants, and learned about the hidden save of an initial value, scope, and uninitialised variables. The previous article, Fortran program structure, describes how a program is laid out; the next one, Fortran data types and kinds, goes through the intrinsic types.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Fortran tutorials.