1

I have a derived-type with pointer (or allocatable) component

type  Tmy
  real, dimension(:), pointer :: vals
  integer :: nVals 
end type Tmy

And I want to create a parameter, e.g. to pass it to a subroutine as intent(in):

type (Tmy), parameter, public :: my_missing = Tmy(null(), 0)

Currently a similar code compiles fine to me by GNU Fortran (Spack GCC) 9.4.0, but introduction of the parameter triggers numerous strange errors in another module that uses the current one. The using module has variables of the type, but no reference to the parameter. The first error is triggered in a derived-type declaration with default initialization:

      550 |     logical, dimension(:,:), pointer :: ifValid => null()   
          |                                                         1
 Error: Cannot change attributes of USE-associated symbol null at (1)

and follows by numerous similar errors and complains about missing members in various structures. If I comment out the parameter declaration the code compiles and runs just fine.

So the questions are:

  1. How introducing a parameter in one module can trigger compilation errors in another module, given that the name my_missing is unique within the project? Or is it just a bug in the compiler?
  2. Is introducing such a parameter a valid practice in Fortran?
  3. If it is valid, what is the effect of assigning this parameter to a structure that has vals already allocated (in case if vals is declared as allocatable)?

PS Yes, I know that allocating pointers is a bad idea. I try to turn them to allocatables bit by bit..

UPD: The issue is reproducible with two different versions of gfortran, but only at one specific computer. Also I did not manage to compile any observable MWE so far..

UPD2: Thank you all, who commented so far. It seems clear that there is no breaking of Fortran standards in my examples here. MWE is of little use since the issue is reproducible only at one computer. I'll then ask for help from our HPC staff and come back once something interesting found.

Roux
  • 435
  • 3
  • 12
  • 1
    Please show us a [mre], so we don't have to guess certain aspects. – francescalus Jan 27 '23 at 12:42
  • How do you know that the definition of `type(Tmy)` contributes to the error elsewhere? – John Alexiou Jan 27 '23 at 12:56
  • 3
    It's almost as if the compiler thinks the use of `null` in line 550 refers to a symbol use associated from OP's own code, rather than the intrinsic routine. I can't see anything wrong in the declaration statement for the parameter, but I am not a Fortran compiler. Perhaps try with a more recent version of the compiler, or another compiler entirely? It wouldn't surprise me to find that OP is exercising a very dusty, and rarely visited, corner of the language specification, one for which compiler support is hitherto little tested in the field. – High Performance Mark Jan 27 '23 at 14:00
  • 2
    I agree with @HighPerformanceMark despite him not being a Fortran compiler - the error message suggests the code itself has a use associated symbol called `Null`. Is there anything in the code called `Null`? But really, a minimal example would help soooo much. And BTW in Fortran we normally call them arguments rather than parameters. – Ian Bush Jan 27 '23 at 15:01
  • 1
    (@IanBush, in this case we'd call them _named constants_ instead of parameters.) – francescalus Jan 27 '23 at 15:38
  • @francescalus ah, my bad. Missed that attribute. Thank you – Ian Bush Jan 27 '23 at 15:40
  • @JohnAlexiou I just comment out one line, do `make clean` and `make` and the thing compiles. I uncomment the line and get a bunch of errors from another module.. – Roux Jan 27 '23 at 17:16
  • 3
    Too much information missing. Really, just make a minimal example. My thought is that `parameter` constants need to be determined at compile time, and allocation does not go with that. – Victor Eijkhout Jan 27 '23 at 17:21
  • I wouldn't be surprised if your makefile doesn't capture your module dependencies correctly. Changing a module is essentially a breaking a change for all dependent modules. You don't need the `parameter` attribute to pass a variable as a dummy argument with `intent(in)`. Also, you can use default values in your derived type to initialize the object. In that case you don't need to pass anything to the structure constructor. – IPribec Jan 27 '23 at 21:07

1 Answers1

0

TL;DR

Bug in gfortran-9 (9.4.0 from Spack, 9.5.0-1ubuntu1~22.04). Other gfortran compilers available for Ubuntu 22.04 (10.4.0-4ubuntu1~22.04,11.3.0-1ubuntu1~22.04, and 12.1.0-2ubuntu1~22.04) work just fine.

Details

I have managed to reproduce the issue in Ubuntu 20.04, by changing to gcc-9. Here is the way to reproduce it:

  1. Make sure that gcc-9 is called for gfortran
  2. Checkout and compile https://github.com/fmidev/silam-model/ See README there for more details
  3. Edit source/namelist.silam.mod.f90 with adding after the definition of Tsilam_namelist (around l. 257):
! Enabling these lines causes a mysterious error at  GNU Fortran 9.4.0 and 9.5.0
  type(Tsilam_namelist), parameter, private  ::  silam_namelist_missing = Tsilam_namelist( &
                                  & null(), int_missing, int_missing, int_missing, &
                                  & silja_false, "Missing_namelist" &
                                  & )  
  1. make clean
  2. make full

The problematic lines were added in our development branch quite some time ago. The only way to pinpoint the line that triggers the bug was a bisect on many revisions. Luckily, the revision that introduced the trigger was small.

The specific bug in gcc-9 responsible for the problem is yet unknown, but it is more of an academic interest...

Thank everyone once again for valuable comments!

Roux
  • 435
  • 3
  • 12