Silverfrost Forums

Welcome to our forums

Compiler issues strange error message for correct code

6 Sep 2023 5:54 #30539

The following code is correct Fortran (checked with Gfortran).

module pars_m
   implicit none
   integer, parameter :: NMAX = 101, MMAX = 50
end module pars_m

module l2_c
   use pars_m
   implicit none
   real x(NMAX)
end module

module l3_c
   use pars_m
   implicit none
   real dgtp(MMAX,NMAX)
end module

module l4_c
   implicit none
   real fx
end module

module comnset_m     ! combine contents and rename some
   use l2_c
   use l3_c, gg => dgtp
   use l4_c
   implicit none
   integer :: n, nili, ninl, neli, nenl
end module

subroutine tp1(mode)
   use comnset_m
   implicit none
   integer    mode
   if (mode == 1) then
      n=2
      nili=0
      ninl=0
      neli=0
      nenl=0
      x(1)=-2.d0
      x(2)=1.d0
   else
      fx=100.d0*(x(2)-x(1)**2)**2+(1.d0-x(1))**2
   endif
   return
end

The compiler issues a strange error message:

ERROR S:\ALGO\NLPQP\tbed\salbug\salgg.F90 32:  Variable GG has already been declared as part of the COMMON block /@@L3_C!DGTP/

The code itself contains no COMMON blocks. The variable GG is in scope in the subroutine, but is not referenced at all.

7 Sep 2023 5:42 #30540

mecej4

Thank you for the bug report. I have logged this for fixing.

11 Nov 2023 9:00 #30727

mecej4

This error report has been suppressed for a future release of FTN95 but the final outcome depends on how GG is accessed.

At the moment FTN95 only allows the GG renaming to be used within the module (comnset_m) where the renaming occurs. This detail of the Fortran standard might be open to interpretation and hence be compiler dependent.

12 Nov 2023 2:54 #30733

Thanks, Paul.

Your statement, 'FTN95 only allows the renaming to be used within the module where the renaming occurs' startled me somewhat, so I created another short test program to probe the issue.

module m1_mod
   implicit none
   integer :: ijk = 1234
end module

module m2_mod
   implicit none
   integer :: ijk = 4231
end module

module m12_mod
   use m1_mod
   use m2_mod, kji => ijk
end module

program tstmod
   use m12_mod
   implicit none
   print *,'ijk = ',ijk,'   kji = ',kji
end program

FTN95 (32-bit), Gfortran and NAG Fortran give the output

 ijk =  1234    kji =  4231

but FTN95 /64 gives

 ijk =         1234   kji =            0

On this question, Section 11.2.2 of the F2008 says, '...The entities in the scoping unit are use associated with the entities in the module. The entities made accessible are identified by the names or generic identifiers used to identify them in the module. By default, the local entities are identified by the same identifiers in the scoping unit containing the USE statement, but it is possible to specify that different local identifiers are used.' Does this not imply that each USE statement adds a list of variables and other entities to a collection of currently accessible variables and entities, cumulatively?

12 Nov 2023 8:02 #30738

mecej4

Thanks for the feedback.

I can confirm that FTN95 currently behaves differently (from gFortran) in this respect (i.e. in the developers' version of FTN95).

I am not sure if this is a bug or if it reflects a different interpretation of the Standard.

Anyway I will log it as a bug that needs fixing.

23 Nov 2023 9:05 #30769

This failure has now been fixed for the next release of FTN95.

I guess that the reason this failure has only now become apparent is that it seems natural to only use a renamed variable within the current module.

23 Nov 2023 12:46 #30772

Thanks, Paul. We may be seeing an instance of the old ways clashing with the new ways.

I have seen many instances in venerable Fortran code where a variable is a member of a common block that is used in several subprograms that are to be used together, but there is at least one subprogram where that variable is passed as an argument rather than through the common block. When one converts such code by replacing common blocks with modules, the issue of this thread comes into play.

Here is an example, the file www.netlib.org/ode/mirkdc.f:

S:\ALGO\ODE\MIRK\netlib>grep -in 'common */rk_method' mirkdc.f
3761:        common   /rk_method/ amethod
4324:         common   /rk_method/ method
7279:        common   /rk_method/ method

Note the use of 'amethod' instead of 'method' on line 3761, to enable 'method' to be passed as an argument:

S:\ALGO\ODE\MIRK\netlib>grep -in 'subroutine interp_tableau (method)' mirkdc.f
3656:      subroutine interp_tableau (method)
Please login to reply.