1

I'm learning the basics of Fortran. I created a simple subroutine initializing a matrix:

program test
   integer, parameter :: n = 1024
   real :: a(n, n)
   call init(a)
   write (*, *) a(1, 1)
end program

subroutine init(a)
   real :: a(n, n)
   a(:, :) = 3.0
end subroutine

Then the output is 0.0 instead of expected 3.0. Apart from that, valgrind says that:

==7006== Conditional jump or move depends on uninitialised value(s)
==7006==    at 0x400754: init_ (in /home/marcin/proj/mimuw/fortran/test)
==7006==    by 0x4007A4: MAIN__ (in /home/marcin/proj/mimuw/fortran/test)
==7006==    by 0x40083B: main (in /home/marcin/proj/mimuw/fortran/test)

Why? The n parameter is correctly recognized by the compiler and should be a global one.

I compiled the program with gfortran 6.3.1

4
  • Perhaps you are thinking of an internal procedure. Commented Feb 3, 2017 at 12:59
  • 2
    n isn't a global object. If you add implicit none in the subroutine you will see an error. Commented Feb 3, 2017 at 13:11
  • Oh, so I need implicit none in the subroutines too! Did not know about it. When testing I tried using that in program but not in the subroutine. Is it possible to use implicit none globally? Commented Feb 3, 2017 at 13:40
  • Because of the independent compilation nature of various program units (as touched on by Vladimir F), there's no such thing really as "globally" for scoping. You can find detail about implicit typing rules in this question. Commented Feb 3, 2017 at 14:25

2 Answers 2

6

n is not a global variable, it is a local variable of the main program.

The subroutine is a completely independent compilation unit from the main program and they do not share any information.

A subroutine can "see" other variables of the parent module, if it is a module procedure, or variables of a parent (host) procedure or program if it is an internal procedure.

Be sure to read about the structure of Fortran programs and use modules as much as possible. Prefer modules over internal procedures. You will see how to put the subroutine into a module or how to make it internal to the main program in the link.

I did not mention common blocks, just don't use them, they are obsolete. And rember to use implicit none in every compilation unit.

Sign up to request clarification or add additional context in comments.

2 Comments

So n was just implicitly declared when I used it in the subroutine?
@marmistrz yes, with implicit typing everything that starts with i,n and some other letters(don't even remember which ones) are declared as integers. Generally you should not use implicit typing since this may lead to undesired behavior sometimes. I can suggest reading Modern Fortran Explained by Michael Metcalf - this can help you with onboarding process.
2

Assuming that you want it everywhere, then one uses a COMMON block in the f77 era, and a MODULE now.

I CAPITALISED most of the changes. And if there is no error gives a few ways to consider understanding N in the SUBROUTINE, and an ELEMENTAL FUNCTION would likely be worthwhile to try here too.

MODULE MyMODULE
  integer, parameter :: n = 1024
END MODULE MyMODULE

!%%%%%%%%%% 
program test
USE MyModule
IMPLICIT NONE
! done up in ˆmoduleˆ...!  integer, parameter :: n = 1024
REAL, DIMENSION(n,n) :: A

CALL Alternative_Init(A, 3.3)
WRITE (*,*) a(1, 1)

CALL Alternative2_Init(A, n, 1.23)
WRITE (*,*) a(1, 1)

call init(a)
write (*, *) a(1, 1)
END PROGRAM TEST

!%%%%%%%%%% 
subroutine init(a)
USE MyModule
IMPLICIT NONE

real :: a(n, n)
a(:, :) = 3.0

RETURN
END SUBROUTINE init


!%%%%%%%%%% 
SUBROUTINE Alternative_Init(a, Val4A)
USE MyModule
IMPLICIT NONE

REAL, DIMENSION(:,:) , INTENT(INOUT) :: a
REAL                 , INTENT(IN  )  :: Val4A

a(:, :) = Val4A
! or just... A = Val4A ! which does them all too.

RETURN
END SUBROUTINE Alternative_Init

!%%%%%%%%%% 
SUBROUTINE Alternative2_Init(a, n, Val4A)
!!!!  USE MyModule
IMPLICIT NONE

INTEGER              , INTENT(IN   ) :: n
REAL, DIMENSION(n,n) , INTENT(  OUT) :: a
REAL                 , INTENT(IN   ) :: Val4A

A = Val4A

RETURN
END SUBROUTINE Alternative2_Init

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.