Nicholas Kinar
Nicholas Kinar

Reputation: 1470

Unexpected data declaration error in Fortran when creating array

I've written a simple test program to demonstrate a data declaration error that I am receiving when compiling some Fortran code. The compile error occurs on a line where I am trying to create an array of arbitrary size. In C code, I believe that this would be accomplished with a simple malloc, but this type of methodology may not be useful in Fortran.

What is going wrong here, and how might I fix it? I am using the gfortran compiler on GNU/Linux, so I think that it would be possible to use all of the supported language features.

Here is my test program:

program test
implicit none
    integer num1, num2

    print *, 'Starting...'
    num1 = 10
    num2 = 11
    call sub(num1, num2)
    print *, 'Done.'

end program



subroutine sub(num1, num2)
    integer num1, num2
    integer num3

    num3 = num1 + num2 - 1
    integer A(num3)

    do i = 1,num3
        A(i) = i
    end do

    print *, 'Now printing out vector'

    do i = 1,num3
        print *, A(i)
    end do
end subroutine

Here is the cmake script being used to compile my simple test program:

cmake_minimum_required (VERSION 2.6)
project (test Fortran)

add_executable( test
test.f90
) # end

When compiling this program, I receive the following error:

/media/RESEARCH/SAS2-version2/test-Q-filter/test-Fcreation/test.f90:20.16:

 integer A(num3)
                1
Error: Unexpected data declaration statement at (1)
/media/RESEARCH/SAS2-version2/test-Q-filter/test-Fcreation/test.f90:23.10:

  A(i) = i
          1
Error: Unexpected STATEMENT FUNCTION statement at (1)
make[2]: *** [CMakeFiles/test.dir/test.f90.o] Error 1
make[1]: *** [CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2

Upvotes: 4

Views: 24121

Answers (1)

The problem is, because you placed a data declaration statement after a normal statement.

You do not have to use user defined dynamic allocation, the so called automatic allocation is enough. (It works also in C99 AFAIK, but only for stack allocations). Just replace

num3 = num1 + num2 - 1
integer A(num3)

with

integer A(num1 + num2 - 1)
integer num3

num3 = num1 + num2 - 1

.

Unfortunately, you cannot just write

integer :: num3 = num1 + num2 - 1

because the variable would be implicitly SAVE and num1 and num2 would have to be known at compile time.

Note I didn't check for other errors.

As a completely different issue I recommend you to use mudules for all your subroutines. In this simple case also an internal subroutine one would do. You have an explicit interface then and you can check for consistency of your calls and use more advanced features.

Upvotes: 9

Related Questions