how to allocate a array in subroutine

  • Follow


Variable a is a allocatable one- or multi- dimension array. The size
of a is dicided in subroutine inital.

I hope to allocate and initial a in subroutine inital. The compiler
prompt error.

So, any idea is welcomed.

The code is listed as follows:
---------------------------main.f90----------------------------------
program main
use testmodule

integer, dimension( : ), allocatable :: a

integer :: n, i

call inital( a )

do i = 1, n
     print *, a( i )
end do
end program main
-----------------------------------------------------------------------

-----------------------------
test.f90----------------------------------
module testmodule
contains
subroutine inital( x )
integer, dimension( : ), intent( out ) :: x
integer :: n, i
n = 10
allocate( x( 1 : n ) )

do i = 1, n
    x( i ) = i
end do

return
end module testmodule
-----------------------------------------------------------------------

0
Reply leed2005 (11) 5/15/2009 7:27:43 AM

leed <leed2005@gmail.com> wrote:
< Variable a is a allocatable one- or multi- dimension array. 
< The size of a is dicided in subroutine inital.
 
< I hope to allocate and initial a in subroutine inital. 
< The compiler prompt error.

(snip)

< module testmodule
< contains
< subroutine inital( x )
< integer, dimension( : ), intent( out ) :: x
< integer :: n, i
< n = 10
< allocate( x( 1 : n ) )

initial is in a module, such that main know that x is allocatable,
but you didn't declare x as allocatable.

-- glen
0
Reply gah (12258) 5/15/2009 7:59:13 AM


On 15 May, 08:27, leed <leed2...@gmail.com> wrote:
> Variable a is a allocatable one- or multi- dimension array. The size
> of a is dicided in subroutine inital.
>
> I hope to allocate and initial a in subroutine inital. The compiler
> prompt error.
>
> So, any idea is welcomed.
>
> The code is listed as follows:

Snip code

Well before we get to that the code has two problems
1) You are missing an End Subroutine statememnt for initial
2) n is being used uninitialized in main

So let's fix those and try to compile:

Wot now ? cat all.f90
Module testmodule

  Integer :: n = 10

Contains
  Subroutine inital( x )
    Integer, Dimension( : ), Intent( out ) :: x
    Integer :: i
    Allocate( x( 1 : n ) )

    Do i = 1, n
       x( i ) = i
    End Do

    Return
  End Subroutine inital
End Module testmodule

Program main
  Use testmodule

  Integer, Dimension( : ), Allocatable :: a

  Integer :: i

  Call inital( a )

  Do i = 1, n
     Print *, a( i )
  End Do
End Program main
Wot now ? gfortran -Wall -Wextra -pedantic -O all.f90
all.f90:9.15:

    Allocate( x( 1 : n ) )
              1
Error: Expression in ALLOCATE statement at (1) must be ALLOCATABLE or
a POINTER
all.f90:20.16:

  Use testmodule
               1
Fatal Error: Can't open module file 'testmodule.mod' for reading at
(1): No such file or directory

OK - it appears x should be allocatable or a pointer, so let's try the
obvious

Wot now ? cat all.f90
Module testmodule

  Integer :: n = 10

Contains
  Subroutine inital( x )
    Integer, Dimension( : ), Allocatable, Intent( out ) :: x
    Integer :: i
    Allocate( x( 1 : n ) )

    Do i = 1, n
       x( i ) = i
    End Do

    Return
  End Subroutine inital
End Module testmodule

Program main
  Use testmodule

  Integer, Dimension( : ), Allocatable :: a

  Integer :: i

  Call inital( a )

  Do i = 1, n
     Print *, a( i )
  End Do
End Program main
Wot now ? gfortran -Wall -Wextra -pedantic -O all.f90
Wot now ? ./a.out
           1
           2
           3
           4
           5
           6
           7
           8
           9
          10

Wasn't that easy ? Also it's hiding a whole load of stuff

1) Let's try a slightly different compile line:

Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
all.f90:7.60:

    Integer, Dimension( : ), Allocatable, Intent( out ) :: x
                                                           1
Error: Fortran 2003: ALLOCATABLE attribute with DUMMY attribute at (1)
all.f90:9.15:

    Allocate( x( 1 : n ) )
              1
Error: Syntax error in ALLOCATE statement at (1)
all.f90:12.7:

       x( i ) = i
      1
Error: Unclassifiable statement at (1)
all.f90:20.16:

  Use testmodule
               1
Fatal Error: Can't open module file 'testmodule.mod' for reading at
(1): No such file or directory

The extra flag means "please conform to the fortran 95 standard."
Allocatable dummy arguments only came into the standard in 2003,
though many many compilers have them implemented even if they are not
full fortran 2003 compilers. The reason for this is that the work on
this part of the 2003 standard was finished fairly soon after the f95
standard was ratified and published as a Technical report (ISO/IEC
15581 TR :1998(E) according to MR&C), so allowing compiler writers to
implement these features early. However you should be aware of this in
case your coding standards demand f95, or if you are using old
versions of compilers ( where this was not implemented, or had bugs )

If you want to avoid f2003 for whatever reason two possible works
arounds are either to use a pointer ( suprise, suprise ! )

Wot now ? cat all.f90
Module testmodule

  Integer :: n = 10

Contains
  Subroutine inital( x )
    Integer, Dimension( : ), Pointer :: x
    Integer :: i
    Allocate( x( 1 : n ) )

    Do i = 1, n
       x( i ) = i
    End Do

    Return
  End Subroutine inital
End Module testmodule

Program main
  Use testmodule

  Integer, Dimension( : ), Pointer :: a

  Integer :: i

  Call inital( a )

  Do i = 1, n
     Print *, a( i )
  End Do
End Program main
Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
Wot now ? ./a.out
           1
           2
           3
           4
           5
           6
           7
           8
           9
          10

( note the lack of intent on the dummy argument )

or to employ use association

Module testmodule

  Integer, Dimension( : ), Allocatable :: a

Contains
  Subroutine inital( n_a )

    Integer, Intent( In ) :: n_a

    Integer :: i

    Allocate( a( 1:n_a ) ) ! Should check stat !!!!!!

    Do i = 1, n_a
       a( i ) = i
    End Do

    Return
  End Subroutine inital
End Module testmodule

Program main
  Use testmodule

  Integer :: i
  Integer :: n = 10

  Call inital( n )

  Do i = 1, n
     Print *, a( i )
  End Do
End Program main
Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
Wot now ? ./a.out
           1
           2
           3
           4
           5
           6
           7
           8
           9
          10

I would use the second route ( use association ) - pointers are best
avoided in Fortran, allocatables are much safer.

2) Through using a module ( excellent ) you avoided most of the other
nasties, but you should be aware that to use either the allocatable
dummy argument or pointer route you need an interface in scope at the
calling point. You get this for free when you call a module
subprogram, but if you don't understand what I mean by this it is
worth looking at a book for a few minutes to understand the concept,
it can save you some misconceptions further down the line. You might
also want to look at the recent thread

http://groups.google.co.uk/group/comp.lang.fortran/browse_thread/thread/c6621b97f448b516?hl=en#

Hope this helps,

Ian

0
Reply ianbush.throwaway.account (88) 5/15/2009 8:07:08 AM

Thanks for your explain.

It truly works for me.


On 5$B7n(B15$BF|(B, $B2<8a(B4$B;~(B07$BJ,(B, Ian Bush <ianbush.throwaway.acco...@googlemail.com>
wrote:
> On 15 May, 08:27, leed <leed2...@gmail.com> wrote:
>
> > Variable a is a allocatable one- or multi- dimension array. The size
> > of a is dicided in subroutine inital.
>
> > I hope to allocate and initial a in subroutine inital. The compiler
> > prompt error.
>
> > So, any idea is welcomed.
>
> > The code is listed as follows:
>
> Snip code
>
> Well before we get to that the code has two problems
> 1) You are missing an End Subroutine statememnt for initial
> 2) n is being used uninitialized in main
>
> So let's fix those and try to compile:
>
> Wot now ? cat all.f90
> Module testmodule
>
>   Integer :: n = 10
>
> Contains
>   Subroutine inital( x )
>     Integer, Dimension( : ), Intent( out ) :: x
>     Integer :: i
>     Allocate( x( 1 : n ) )
>
>     Do i = 1, n
>        x( i ) = i
>     End Do
>
>     Return
>   End Subroutine inital
> End Module testmodule
>
> Program main
>   Use testmodule
>
>   Integer, Dimension( : ), Allocatable :: a
>
>   Integer :: i
>
>   Call inital( a )
>
>   Do i = 1, n
>      Print *, a( i )
>   End Do
> End Program main
> Wot now ? gfortran -Wall -Wextra -pedantic -O all.f90
> all.f90:9.15:
>
>     Allocate( x( 1 : n ) )
>               1
> Error: Expression in ALLOCATE statement at (1) must be ALLOCATABLE or
> a POINTER
> all.f90:20.16:
>
>   Use testmodule
>                1
> Fatal Error: Can't open module file 'testmodule.mod' for reading at
> (1): No such file or directory
>
> OK - it appears x should be allocatable or a pointer, so let's try the
> obvious
>
> Wot now ? cat all.f90
> Module testmodule
>
>   Integer :: n = 10
>
> Contains
>   Subroutine inital( x )
>     Integer, Dimension( : ), Allocatable, Intent( out ) :: x
>     Integer :: i
>     Allocate( x( 1 : n ) )
>
>     Do i = 1, n
>        x( i ) = i
>     End Do
>
>     Return
>   End Subroutine inital
> End Module testmodule
>
> Program main
>   Use testmodule
>
>   Integer, Dimension( : ), Allocatable :: a
>
>   Integer :: i
>
>   Call inital( a )
>
>   Do i = 1, n
>      Print *, a( i )
>   End Do
> End Program main
> Wot now ? gfortran -Wall -Wextra -pedantic -O all.f90
> Wot now ? ./a.out
>            1
>            2
>            3
>            4
>            5
>            6
>            7
>            8
>            9
>           10
>
> Wasn't that easy ? Also it's hiding a whole load of stuff
>
> 1) Let's try a slightly different compile line:
>
> Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
> all.f90:7.60:
>
>     Integer, Dimension( : ), Allocatable, Intent( out ) :: x
>                                                            1
> Error: Fortran 2003: ALLOCATABLE attribute with DUMMY attribute at (1)
> all.f90:9.15:
>
>     Allocate( x( 1 : n ) )
>               1
> Error: Syntax error in ALLOCATE statement at (1)
> all.f90:12.7:
>
>        x( i ) = i
>       1
> Error: Unclassifiable statement at (1)
> all.f90:20.16:
>
>   Use testmodule
>                1
> Fatal Error: Can't open module file 'testmodule.mod' for reading at
> (1): No such file or directory
>
> The extra flag means "please conform to the fortran 95 standard."
> Allocatable dummy arguments only came into the standard in 2003,
> though many many compilers have them implemented even if they are not
> full fortran 2003 compilers. The reason for this is that the work on
> this part of the 2003 standard was finished fairly soon after the f95
> standard was ratified and published as a Technical report (ISO/IEC
> 15581 TR :1998(E) according to MR&C), so allowing compiler writers to
> implement these features early. However you should be aware of this in
> case your coding standards demand f95, or if you are using old
> versions of compilers ( where this was not implemented, or had bugs )
>
> If you want to avoid f2003 for whatever reason two possible works
> arounds are either to use a pointer ( suprise, suprise ! )
>
> Wot now ? cat all.f90
> Module testmodule
>
>   Integer :: n = 10
>
> Contains
>   Subroutine inital( x )
>     Integer, Dimension( : ), Pointer :: x
>     Integer :: i
>     Allocate( x( 1 : n ) )
>
>     Do i = 1, n
>        x( i ) = i
>     End Do
>
>     Return
>   End Subroutine inital
> End Module testmodule
>
> Program main
>   Use testmodule
>
>   Integer, Dimension( : ), Pointer :: a
>
>   Integer :: i
>
>   Call inital( a )
>
>   Do i = 1, n
>      Print *, a( i )
>   End Do
> End Program main
> Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
> Wot now ? ./a.out
>            1
>            2
>            3
>            4
>            5
>            6
>            7
>            8
>            9
>           10
>
> ( note the lack of intent on the dummy argument )
>
> or to employ use association
>
> Module testmodule
>
>   Integer, Dimension( : ), Allocatable :: a
>
> Contains
>   Subroutine inital( n_a )
>
>     Integer, Intent( In ) :: n_a
>
>     Integer :: i
>
>     Allocate( a( 1:n_a ) ) ! Should check stat !!!!!!
>
>     Do i = 1, n_a
>        a( i ) = i
>     End Do
>
>     Return
>   End Subroutine inital
> End Module testmodule
>
> Program main
>   Use testmodule
>
>   Integer :: i
>   Integer :: n = 10
>
>   Call inital( n )
>
>   Do i = 1, n
>      Print *, a( i )
>   End Do
> End Program main
> Wot now ? gfortran -Wall -Wextra -pedantic -O -std=f95 all.f90
> Wot now ? ./a.out
>            1
>            2
>            3
>            4
>            5
>            6
>            7
>            8
>            9
>           10
>
> I would use the second route ( use association ) - pointers are best
> avoided in Fortran, allocatables are much safer.
>
> 2) Through using a module ( excellent ) you avoided most of the other
> nasties, but you should be aware that to use either the allocatable
> dummy argument or pointer route you need an interface in scope at the
> calling point. You get this for free when you call a module
> subprogram, but if you don't understand what I mean by this it is
> worth looking at a book for a few minutes to understand the concept,
> it can save you some misconceptions further down the line. You might
> also want to look at the recent thread
>
> http://groups.google.co.uk/group/comp.lang.fortran/browse_thread/thre...
>
> Hope this helps,
>
> Ian

0
Reply leed2005 (11) 5/15/2009 3:21:56 PM

On May 15, 4:07=A0am, Ian Bush
<ianbush.throwaway.acco...@googlemail.com> wrote:
> On 15 May, 08:27, leed <leed2...@gmail.com> wrote:
>
> > Variable a is a allocatable one- or multi- dimension array. The size
> > of a is dicided in subroutine inital.
>
> > I hope to allocate and initial a in subroutine inital. The compiler
> > prompt error.
>
> > So, any idea is welcomed.
>
> > The code is listed as follows:
>
> Snip code
>
> Well before we get to that the code has two problems
> 1) You are missing an End Subroutine statememnt for initial
> 2) n is being used uninitialized in main

snip code

Without fixing #2, I obtained these strange results:

using g95 =3D gcc version 4.1.2 (g95 0.92!) May  7 2009

on this test program:

module testmodule
contains
subroutine inital( x )
integer, dimension( : ), intent( out ), allocatable :: x !#
integer :: n, i
n =3D 10
allocate( x( 1 : n ) )

do i =3D 1, n
    x( i ) =3D i
end do
return
end subroutine inital !#
end module testmodule

program main
use testmodule
integer, dimension( : ), allocatable :: a
integer :: n, i

call inital( a )
do i =3D 1, n
     print *, a( i )
end do
end program main

N is undefined in the main program, yet:

C:\temp>g95 u.f90

C:\temp>a
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

As expected, it's not legal f95.

C:\temp>g95 -std=3Df95 u.f90
In file u.f90:4

integer, dimension( : ), intent( out ), allocatable :: x !#
                                                       1
Error: ALLOCATABLE attribute conflicts with DUMMY attribute at (1)
In file u.f90:7

allocate( x( 1 : n ) )
            1
Error: Unexpected array reference at (1)
In file u.f90:10

    x( i ) =3D i
     1
Error: Unexpected array reference at (1)

Compiling as f2003 gives:

C:\temp>g95 -std=3Df2003 u.f90

C:\temp>a

C:\temp>g95 -Wall -Wextra u.f90
In file u.f90:23

integer :: n, i
           1
Warning (113): Variable 'n' at (1) is used but not set

Yes, I know that the value of N is unset!
It's not really a bug, because the program is not standard conforming,
but why does it still work?
IMO, N is in a different LOCAL scope.

-- e

0
Reply epc8 (1259) 5/15/2009 7:14:42 PM

"leed" <leed2005@gmail.com> wrote in message
news:9cced4e5-e7ca-433a-ad5e-d939a765b54e@y34g2000prb.googlegroups.com...
> Variable a is a allocatable one- or multi- dimension array. The size
> of a is dicided in subroutine inital.

I don't know whether you have something more elaborate in mind
when presenting those procedures.

However, just to initialize an array as you have shown
have you considered:

A = (/ (I, I=1,10) /)

Using a subroutine to do that is sort of overkill.

(You will need to allocate A first, of course).



> I hope to allocate and initial a in subroutine inital. The compiler
> prompt error.
>
> So, any idea is welcomed.
>
> The code is listed as follows:
> ---------------------------main.f90----------------------------------
> program main
> use testmodule
>
> integer, dimension( : ), allocatable :: a
>
> integer :: n, i
>
> call inital( a )
>
> do i = 1, n
>      print *, a( i )
> end do
> end program main
> -----------------------------------------------------------------------
>
> -----------------------------
> test.f90----------------------------------
> module testmodule
> contains
> subroutine inital( x )
> integer, dimension( : ), intent( out ) :: x
> integer :: n, i
> n = 10
> allocate( x( 1 : n ) )
>
> do i = 1, n
>     x( i ) = i
> end do
>
> return
> end module testmodule
> -----------------------------------------------------------------------


0
Reply robin_v (2738) 5/18/2009 1:29:25 AM

5 Replies
40 Views

(page loaded in 0.137 seconds)

Similiar Articles:













7/20/2012 7:13:23 PM


Reply: