Общий тип, производный от Фортрана: инициализация?

У меня проблемы с этим общим:

      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

Пытаясь скомпилировать некоторый код, включая этот общий, я получаю:

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

Будучи не очень знакомым с Фортраном, я не понимаю, в чем проблема, или как ее решить (я пытался гуглить безуспешно). Если я использую REAL(8) вместо double_stвсе работает нормально.

Может ли кто-нибудь помочь мне в этом?

2 ответа

Решение

С линии

integer :: acc = -1

скинуть задний ход

 = -1

покидать, оставлять

integer :: acc

перекомпилируйте и посмотрите, что получится. Сообщение об ошибке предполагает, что программа не может инициализировать компонент производного типа и использовать переменные этого производного типа в common заявления. "Инициализация" используется в стандартах Фортрана для точного определения значения переменной (или элемента) в ее объявлении.

В моей (черновой) версии стандарта Fortran 2008 ограничение 506 на правило 503 запрещает инициализацию компонентов переменных производного типа, используемых в общих блоках. Этот запрет, похоже, не распространяется на инициализацию переменных встроенных типов, следовательно, принятие компилятором кода, когда переменная имеет тип real(8),

Что касается использования производных типов в общих блоках, это программирование смешанной парадигмы, если когда-либо было такое!

Я говорю почти так же, как в ответе High Performance Mark, но, надеюсь, с немного большей проработкой. После редактирования этого ответа я на самом деле немного расходится.

Наличие объявления типа

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), которое говорит, что

Если объект общего блока имеет производный тип, тип должен иметь атрибут BIND или атрибут SEQUENCE и не должен иметь инициализации по умолчанию.

Это то, на что жалуются компиляторы. Используя real(kind(0d0)) (или же real(8)) не нарушает это ограничение. Внутренние типы (такие как real) не может иметь инициализацию по умолчанию, но они могут иметь явную инициализацию (например, real :: hello = 1.). Существуют некоторые ограничения на использование явно инициализированного объекта (такого как C506, упомянутый в другом ответе), но вопрос по этому вопросу недостаточно ясен, чтобы я мог прокомментировать его дальше.

Другие вопросы по тегам