Yifan
Yifan

Reputation: 376

Is initializing a variable in between variable declarations forbidden?

I have something like

integer a
integer b 
b = 0
integer c

a = 0
c = 0

which does not work with the error

"A specification statement cannot appear in the executable section."

However, changing it to

integer a
integer b
integer c

a = 0
b = 0
c = 0 

works.

Upvotes: 1

Views: 367

Answers (3)

user5713492
user5713492

Reputation: 974

The situation is murkier in f2008, with the BLOCK construct. That construct necessarily lies among the executable statements, but is often there for the sole purpose of adding the capability to place some specification statements after executable statements, as when an assumed length pointer is to be pointed at anonymous memory.

EDIT: Example

module anonymous
   use ISO_C_BINDING
   implicit none
   interface
      function malloc(size) bind(C,name='malloc')
         import
         implicit none
         type(C_PTR) malloc
         integer(C_SIZE_T), value :: size
      end function malloc
      subroutine free(ptr) bind(C,name='free')
         import
         implicit none
         type(C_PTR), value :: ptr
      end subroutine free
      function strlen(str) bind(C,name='strlen')
         import
         implicit none
         type(C_PTR), value :: str
         integer(C_SIZE_T) strlen
      end function strlen
   end interface
   contains
      function hello()
         type(C_PTR) hello
         character(LEN=*,KIND=C_CHAR), parameter :: world = &
            'Hello, world'//C_NULL_CHAR
         character(LEN=len(world),KIND=kind(world)), pointer :: fptr
         hello = malloc(len(world,KIND=C_SIZE_T))
         call C_F_POINTER(hello,fptr)
         fptr = world
      end function hello
end module anonymous

program test
   use anonymous
   implicit none
   type(C_PTR) cptr
   character(LEN=:,KIND=C_CHAR), pointer :: fptr
   integer(C_SIZE_T) hello_len
   cptr = hello()
   hello_len = strlen(cptr)
   BLOCK
      character(LEN=hello_len,KIND=C_CHAR), pointer :: temp
      call C_F_POINTER(cptr,temp)
      fptr => temp
   end BLOCK
   write(*,'(*(g0))') fptr(1:strlen(cptr))
end program test

Upvotes: 0

Alexander Vogt
Alexander Vogt

Reputation: 18098

Yes, this is forbidden in Fortran. This is defined in the Fortran 2008 Standard, Cl. 2.3.2 "Statement order":

enter image description here

1 The syntax rules of clause 2.1 specify the statement order within program units and subprograms. These rules are illustrated in Table 2.1 [...]. Table 2.1 shows the ordering rules for statements and applies to all program units, subprograms, and interface bodies. Vertical lines delineate varieties of statements that may be interspersed and horizontal lines delineate varieties of statements that shall not be interspersed. [...] Between USE and CONTAINS statements in a subprogram, nonexecutable statements generally precede executable statements [...]

(Emphasis mine)


[Slightly off-topic, but related] Please note that while

integer :: a
integer :: b = 0
integer :: c

is allowed, this has the side effect that b gets the save attribute. That is typically not what you want...

Upvotes: 4

The error message is quite clear. Fortran programs and subprograms are divided into two parts. First the specification part where you use modules, define variables, derived types, interfaces... And then the executable part where you put the actual executable statements or control structures.

It is not possible to mix them.

Upvotes: 2

Related Questions