Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Dummy array size fortran77

Montaser_B_
Beginner
1,218 Views

Hi,

 

I have a simple program in fortran 77 that I want to pass dynamic array size between the program and the subroutine.

But I encountered a problem with the compiling

the code is as below

            program read_sub
! ********************** Main program *********************************
      implicit none

      integer :: cm(30),n,i,nstress
      integer,allocatable,dimension(:),pointer :: stress
      n=30
      
      nstress=size(cm)
      allocate stress(nstress)
      
      do i=1,n
          cm(i)=10
      enddo

      CALL umat(cm,stress,n,nstress)
                        
      end program read_sub
    

	  subroutine umat(cm,stress,n,nstress)
      integer :: cm(30),n,i,nstress
      integer :: stress(nstress)
      
      do i=1,nstress
          stress(i)=cm(i)+10
      write(*,*) stress(i)
      enddo
    
      end

I think allocate and size doesn't work with fortran 77 but I am not sure.

Any help will be appreciated

 

0 Kudos
5 Replies
Steve_Lionel
Honored Contributor III
1,218 Views

This program is certainly NOT Fortran 77! Not even close!

You have some syntax errors in the program:

1) The ALLOCATE needs to be allocate(stress(nstress))

2) You can't give a variable both the ALLOCATABLE and POINTER attributes. Remove POINTER.

0 Kudos
Montaser_B_
Beginner
1,218 Views

Steve Lionel (Ret.) wrote:

This program is certainly NOT Fortran 77! Not even close!

You have some syntax errors in the program:

1) The ALLOCATE needs to be allocate(stress(nstress))

2) You can't give a variable both the ALLOCATABLE and POINTER attributes. Remove POINTER.

 

Thank you for your reply, I make the changes as you suggested and the program works fine using Visual studio 12

I changed the declaration of the array cm(30) to cm(*) because the software that uses this subroutine declares cm as cm(*)

But it doesn't work

So I tried to use cm(:) insted but also I got this error msg

the error SIZE of array is not computable. [SIZE]

 

The final subroutine should be like this, 

            subroutine read_sub
! ********************** Main program *********************************
      implicit none

      integer :: cm(*),n,i,nstress
      integer,allocatable,dimension(:) :: stress
      n=30
      
      nstress=size(cm)
      allocate(stress(nstress))
      
      do i=1,n
          cm(i)=10
      enddo

      CALL umat(cm,stress,n,nstress)
                        
      end program read_sub
    

	  subroutine umat(cm,stress,n,nstress)
      integer :: cm(30),n,i,nstress
      integer :: stress(nstress)
      
      do i=1,nstress
          stress(i)=cm(i)+15
      write(*,*) stress(i)
      enddo
    
      end

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,218 Views

(*) means "assumed-size" and is valid for dummy arguments only. It means that the size of the array is not known. You should keep the (30) in the main program, or set it to whatever value you want for the size of cm. You could also make it ALLOCATABLE and allocate it to the desired size.

Use of (*) is considered a poor practice nowadays, though it was used a lot in the past. The more modern approach is to declare the dummy argument assumed-shape, with the syntax (:) - this will cause the size to be passed directly by the caller, but this requires an explicit interface to be visible.

Another approach you could take - since nstress has the size of cm you can declare cm in the subroutine as cm(nstress). Just move the declaration of nstress to before that of cm to be standard-conforming.

0 Kudos
Montaser_B_
Beginner
1,218 Views

I want to thank you Mr. Lionel for your help. I tried your last suggestion but it does not work.

            program read_sub

! ********************** Main program *********************************
      implicit none

      integer :: nstress,cm(nstress),n,i
      integer,allocatable,dimension(:) :: stress
      n=30
      
      nstress=size(cm)
      allocate(stress(nstress))
      
      do i=1,n
          cm(i)=10
      enddo

      CALL umat(cm,stress,n,nstress)
                        
      end program read_sub
    

	  subroutine umat(cm,stress,n,nstress)
      integer :: nstress,cm(nstress),n,i
      integer :: stress(nstress)
      
      do i=1,nstress
          stress(i)=cm(i)+15
      write(*,*) stress(i)
      enddo
    
      end

 

I will see my professor if bounding the array up to 30 is ok.

Thank you very much

0 Kudos
mecej4
Honored Contributor III
1,218 Views

You have made inconsistent changes to parts of the program. It is not clear to me what you want the program to do, so I shall confine my comments to the code that you showed in #5.

You cannot use nstress as the dimension of the statically allocated array cm in the main program. You may use a literal or named constant ("parameter" attribute in Fortran) for this purpose. 

The argument n is not used in the subroutine, and could perhaps be omitted.

To use the "END PROGRAM <progname>" statement, you need to start the program with a "PROGRAM <progname>" statement, and the two prog-names must be identical.

 

0 Kudos
Reply