Is initializing a variable in between variable declarations forbidden?

后端 未结 3 1202
日久生厌
日久生厌 2021-01-23 09:42

I have something like

integer a
integer b 
b = 0
integer c

a = 0
c = 0

which does not work with the error

\"A specific

相关标签:
3条回答
  • 2021-01-23 10:14

    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
    
    0 讨论(0)
  • 2021-01-23 10:22

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

    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...

    0 讨论(0)
  • 2021-01-23 10:37

    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.

    0 讨论(0)
提交回复
热议问题