Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Transfer of data from inside a subroutine to main program

Status
Not open for further replies.

Vahid9

Technical User
Jul 28, 2016
23
CA
Hello,

The following program does not compile but returns the following error:

error #6236: A specification statement cannot appear in the executable section.

All I would like to do is to be able to transfer the array r(i) from the subroutine to the main program without using the "contents"
statement. The actual program I am working on is much bigger but the issue is the same, i.e., getting the main program to be able to
use r(i) inside the subroutine.

Program Test
IMPLICIT NONE
real,dimension(1) :: r

CALL f(r)

write(*,*) r

subroutine f(r)
implicit none
integer :: i
real, intent(out) :: r(i)

do i = 1, 10
r = 2*i
enddo
end subroutine
END

Thank you,

Vahid
 
just curious, why not just use a common block then any information put into the common block in the subroutine is available in the main body of the procedure.

Bill
Lead Application Developer
New York State, USA
 
Hi Vahid9,
IMHO, with contains it's more elegant, for example you could do it like this:
vahid9_01.f95
Code:
[COLOR=#800080]program[/color] test
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]1[/color]) :: r1
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]3[/color]) :: r2
  [COLOR=#008b8b]call[/color] f(r1)
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r1= "[/color], r1
  [COLOR=#008b8b]call[/color] f(r2)
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r2= "[/color], r2

[COLOR=#800080]contains[/color]
  [COLOR=#800080]subroutine[/color] f(r)
    [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
    [COLOR=#2e8b57][b]integer[/b][/color] :: i, n
[COLOR=#2e8b57][b]    real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]out[/b][/color]) :: r
    n[COLOR=#a52a2a][b]=[/b][/color][COLOR=#008b8b]size[/color](r)
    [COLOR=#a52a2a][b]do[/b][/color] i [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]1[/color], n
      r(i) [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]2[/color][COLOR=#a52a2a][b]*[/b][/color]i
    [COLOR=#a52a2a][b]enddo[/b][/color]
  [COLOR=#800080]end subroutine[/color]
[COLOR=#800080]end program[/color]

when you want to do it without contains, so for example like this:
vahid9_02.f95
Code:
[COLOR=#800080]program[/color] test
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]1[/color]) :: r1
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]3[/color]) :: r2
  [COLOR=#008b8b]call[/color] f(r1, [COLOR=#ff00ff]1[/color])
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r1= "[/color], r1
  [COLOR=#008b8b]call[/color] f(r2, [COLOR=#ff00ff]3[/color])
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r2= "[/color], r2
[COLOR=#800080]end program[/color]

[COLOR=#800080]subroutine[/color] f(r, n)
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: i, n
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](n), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]out[/b][/color]) :: r
  [COLOR=#a52a2a][b]do[/b][/color] i [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]1[/color], n
    r(i) [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]2[/color][COLOR=#a52a2a][b]*[/b][/color]i
  [COLOR=#a52a2a][b]enddo[/b][/color]
[COLOR=#800080]end subroutine[/color]

Output of both examples is the same:
Code:
mikrom@mikrom-Lenovo-S500 ~/Work/fortran $ ./vahid9_02
 r1=    2.00000000    
 r2=    2.00000000       4.00000000       6.00000000
 
Hi Bill and Mikrom,

Thank you for your responses. I have not used common blocks in the past and so I will look into it.

I tried using "contains" before. The actual code has several other subroutines and using "contains" results in a lot of other errors which
without the subroutine f(r), those errors do not occur.

The vahid9_02.f95 is almost what I am looking for except in my case, there is no input n to the subroutine. The subroutine calculates an array r(i) internally and all I would like is to be able to use that array outside the subroutine.

I am grateful for your suggestions.

Best wishes,
Vahid
 
Hi Vahid9,

In the case without contains I declared the second argument (i.e. n = dimension of the array) in the funcion f(r, n) instead of only f(r), because my compiler (gfortran version 4.8.4) complained that:
Code:
  call f(r1)
        1
Error: Procedure 'f' at (1) with assumed-shape dummy argument 'r' must have an explicit interface

So when you don't want to have f(r, n), but only f(r) you must provide this explicit interface for the subroutine f.
This works for me - I modified vahid9_01.f95, so that I omitted contains and declared interface

vahid9_011.f95
Code:
[COLOR=#800080]program[/color] test
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]1[/color]) :: r1
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]3[/color]) :: r2
  [COLOR=#800080]interface[/color]
    [COLOR=#800080]subroutine[/color] f(r)
      [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
      [COLOR=#2e8b57][b]integer[/b][/color] :: i, n
[COLOR=#2e8b57][b]      real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]out[/b][/color]) :: r
    [COLOR=#800080]end subroutine[/color]
  [COLOR=#800080]end interface[/color]

  [COLOR=#008b8b]call[/color] f(r1)
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r1= "[/color], r1
  [COLOR=#008b8b]call[/color] f(r2)
  [COLOR=#a52a2a][b]write[/b][/color]([COLOR=#a52a2a][b]*[/b][/color],[COLOR=#a52a2a][b]*[/b][/color]) [COLOR=#ff00ff]"r2= "[/color], r2
[COLOR=#800080]end program[/color]

[COLOR=#800080]subroutine[/color] f(r)
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: i, n
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]out[/b][/color]) :: r
  n[COLOR=#a52a2a][b]=[/b][/color][COLOR=#008b8b]size[/color](r)
  [COLOR=#a52a2a][b]do[/b][/color] i [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]1[/color], n
    r(i) [COLOR=#a52a2a][b]=[/b][/color] [COLOR=#ff00ff]2[/color][COLOR=#a52a2a][b]*[/b][/color]i
  [COLOR=#a52a2a][b]enddo[/b][/color]
[COLOR=#800080]end subroutine[/color]

Output
Code:
mikrom@mikrom-Lenovo-S500 ~/Work/fortran $ gfortran vahid9_011.f95 -o vahid9_011mikrom@mikrom-Lenovo-S500 ~/Work/fortran $ ./vahid9_011
 r1=    2.00000000    
 r2=    2.00000000       4.00000000       6.00000000
 
Thank you Mikrom. The interface made it work.

Best wishes,
Vahid
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top