Fortran derived type in common: initialization?

时间:2015-06-15 15:15:28

标签: fortran fortran90 static-initialization

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 个答案:

答案 0 :(得分:3)

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 !

答案 1 :(得分:2)

我和High Performance Mark's answer的说法大致相同,但希望稍微详细一点。在那个答案的编辑后,我实际上有点分歧。

具有类型声明

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

涉及默认初始化。这是acc=1部分:参见Fortran 2008 4.5.4.6。它不仅仅是默认初始化的组件,而是整个类型。

有一个约束(C5105,在5.7.2.1中),表示

  

如果 common-block-object 属于派生类型,则该类型应具有BIND属性或SEQUENCE属性,并且它不应具有默认初始化。

这就是编译器所抱怨的。使用real(kind(0d0))(或real(8))并不违反此约束。内部类型(例如real)不能具有默认初始化,但它们可以具有显式初始化(​​例如real :: hello = 1.)。使用明确初始化的对象有一些限制(例如在另一个答案中提到的C506),但在这一点上我不能清楚地进一步评论。