Question about ENTRY and DATA

Consider the following code:

    subroutine a()
      implicit none 
      real :: u(3)

      print*, 'a'
      goto 1
 
      entry b()         
        print*, 'b'
        data u/ 0.1, 0.2, 0.3 /  
        
1     print*, u   ! what is u here ?

    end subroutine a

    program main 
        call a()
    end program main

The result (using latest gfortran) is:

 a
  0.100000001      0.200000003      0.300000012    

Which I guess sort of suprised me. I would have thought that since the b() entry was never called, that data statement was not executed, but I guess it is? Is that normal for a data statement?

It seems that this refactoring is the same thing:

    subroutine a()
        implicit none 
        real,save :: u(3) = [0.1, 0.2, 0.3]
         
        print*, 'a'
        goto 1
   
        entry b()         
          print*, 'b'
          
  1     print*, u 
  
      end subroutine a

Is that right?

Placing the DATA statements anywhere in the body of the subroutine should be flagged as non-standard if you add the flags to enforce standard conformance. DATA statements are not executables, but are used to initialize the routine at start-up not on each call, so the refactoring is equivalent. In cases where the values will not be changed it is preferable to use PARAMETER instead of SAVE, but the fact they are not changed is not the general case and this is just a small example. In new code using ENTRY is generally deprecated in favor of other methods such as using CONTAINS and a conditional:

subroutine  a(flag)
! shared declarations and code
if(flag) then
   call b()
else
   call c()
endif
contains
subroutine (b)
end
subroutine (c)
end

You can even pass in the routine name and eliminate the conditional and so on.

https://fortran-lang.discourse.group/t/should-the-entry-statement-be-used-in-new-code/2636

https://fortranwiki.org/fortran/show/Modernizing+Old+Fortran

DATA statements may appear almost anywhere in a program unit, but they are indeed not executable.

image

It is just considered obsolescent. I used to do it a lot, but I always place them after the declarations and before the executable statements if I use them now. I guess I phrased that a little too strongly. Probably no compiler enforces not allowing it(?)

 gfortran --std=f2018 nodata.f90
nodata.f90:3:11:

    3 | data a/100/
      |           1
Warning: Obsolescent feature: DATA statement at (1) after the first executable statement
urbanjs@mercury:~$ cat nodata.f90
program nodata
write(*,*)a
data a/100/
end program nodata
urbanjs@mercury:~$ ./a.out
   100.000000    

Yes, the placement is obsolescent, but not deleted. Compilers are required to be able to diagnose the usage.

There is one case where a small module is an easy replacement for a procedure with multiple entries.
When no executable statements are shared, just data:

module M_
! when what is shared between entries is declarations and data
! a module is an easy replacement. Gets more complicated if
! there is shared text as well.

! shared stuff
   implicit none
   private
   public case1, case2
   integer, parameter :: ivals(3) = [100, 200, 300]

contains

   subroutine case1()
      write (*, *) 'case1', ivals
   end subroutine case1

   subroutine case2()
      write (*, *) 'case2', ivals
   end subroutine case2

end module M_

program noentry
   use M_, only: case1, case2
   implicit none
   call case1()
   call case2()
end program noentry

It can be confusing to apply a current or recent version of the Fortran standard to a program in which old/obsolescent features are combined with features that were not present in Fortran 77. The table that @sblionel showed appears to rule out DATA statements in internal procedures, but they are allowed.

    subroutine a()
      implicit none 
      real :: u(3)
      character ep

      data u/ 0.1, 0.2, 0.3 /, ep/'a'/  
      goto 1
 
      entry b()         
        ep = 'b'
        data u/ 0.3, 0.2, 0.1 / ! u is already initialized; error or no effect?
        
1     print *, ep, u   ! what is u here ?

    end subroutine a

    program main 
        
        call a()
        call b()
        call c()
        
        CONTAINS
           subroutine c()
              character ep
              real u(2)
              data u/0.5,0.6/, ep/'c'/
              print *,ep,u
           end subroutine c
    end program main

Try Gfortran on this version with and without -fstd=f2008. Try other compilers.

No it doesn’t. Internal procedures are subroutines or functions, so you start at the top again.The next table in the standard reflects that: