Fortran derived type in common: initialization?

1.5k views Asked by At

I got troubles with this common:

      COMMON /REDCOM/ DPREC,NITMA,INDIC,NBERR,NCAR,KMOTLU,
     &                REDVAR,MOCDER(2)
      COMMON /REDCO1/ CTEXT
C
      type(double_st) :: DPREC
      INTEGER :: NITMA,INDIC,NBERR,NCAR,KMOTLU,REDVAR,MOCDER
      CHARACTER(72) :: CTEXT
      CHARACTER(4)  :: CTEXT4
C
      EQUIVALENCE (CTEXT,CTEXT4)

The double_st derived type is:

  type double_st
     sequence
     real(kind(0.d0)) :: x,y,z
     integer :: acc = -1
  end type double_st

Trying to compile some code including this common, I get:

ifort:

./REDCOM.INC(1): error #6005: A derived type object in a COMMON block shall not have default initialization   [DPREC]
      COMMON /REDCOM/ DPREC,NITMA,INDIC,NBERR,NCAR,KMOTLU,
----------------------^

gfortran:

REDCOM.INC:1.27:
    Included at m_abaq4.f:90:

      COMMON /REDCOM/ DPREC,NITMA,INDIC,NBERR,NCAR,KMOTLU,              
                           1
Error: Derived type variable 'dprec' in COMMON at (1) may not have default initializer

Being not very familiar with Fortran, I don't understand what the problem is, or how to solve it (I tried googling with no success). If I use a REAL(8) instead of a double_st, everything works fine.

Could someone help me on this?

2

There are 2 answers

4
High Performance Mark On BEST ANSWER

From the line

integer :: acc = -1

strip off the trailing

 = -1

to leave

integer :: acc

recompile, and see what happens. The error message suggests that a program can't initialise a derived type component and use variables of that derived type in common statements. 'Initialize' is used in the Fortran standards to mean, precisely, the setting of a variable (or element) 's value in its declaration.

In my (draft) version of the Fortran 2008 standard constraint 506 on rule 503 prohibits initialization of components of variables of derived type used in common blocks. This prohibition doesn't seem to apply to initialization of variables of intrinsic types, hence the compiler's acceptance of the code when the variable is of type real(8).

As for using derived types in common blocks, that's mixed-paradigm programming if ever there was such a thing !

0
francescalus On

I'm saying much the same as in High Performance Mark's answer, but hopefully with a little more elaboration. After that answer's edit I actually diverge a little.

Having the type declaration

type double_st
  sequence
  real(kind(0.d0)) :: x,y,z
  integer :: acc = -1
end type double_st

involves default initialization. That's the acc=1 part: see Fortran 2008 4.5.4.6. It isn't just the component that is default initialized but the whole type.

There is a constraint (C5105, in 5.7.2.1) which says that

If a common-block-object is of a derived type, the type shall have the BIND attribute or the SEQUENCE attribute and it shall have no default initialization.

This is what the compilers complain about. Using a real(kind(0d0)) (or real(8)) doesn't violate this constraint. Intrinsic types (such as that real) cannot have default initialization, but they can have explicit initialization (such as real :: hello = 1.). There are some restrictions on the use of an explicitly initialized object (such as C506 mentioned in the other answer), but the question isn't clear enough on that point for me to comment further.