Fortran 派生类型的共同点:初始化?

Fortran derived type in common: initialization?

我遇到了这个常见问题:

      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)

double_st 派生类型是:

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

尝试编译一些包含此通用代码的代码,我得到:

福特:

./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

对 Fortran 不是很熟悉,我不明白问题是什么,或者如何解决(我尝试谷歌搜索没有成功)。如果我使用 REAL(8) 而不是 double_st,一切正常。

有人可以帮我解决这个问题吗?

来自行

integer :: acc = -1

去掉尾随

 = -1

离开

integer :: acc

重新编译,看看会发生什么。该错误消息表明程序无法初始化派生类型组件并在 common 语句中使用该派生类型的变量。 'Initialize' 在 Fortran 标准中使用,准确地说是在其声明中设置变量(或元素)的值。

在我的(草案)版本的 Fortran 2008 标准约束 506 中,规则 503 禁止初始化公共块中使用的派生类型变量的组件。此禁令似乎不适用于内部类型变量的初始化,因此编译器在变量类型为 real(8).

时接受代码

至于在公共块中使用派生类型,如果有的话,那就是混合范式编程!

我说的和 差不多,但希望能更详细一点。在那个答案的编辑之后,我实际上有点分歧。

有类型声明

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 中)说

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.

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