Общий тип, производный от Фортрана: инициализация?
У меня проблемы с этим общим:
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, упомянутый в другом ответе), но вопрос по этому вопросу недостаточно ясен, чтобы я мог прокомментировать его дальше.