Причина в том, что перегруженное присваивание copy
не поддерживает выделяемые левые части.Поэтому, когда значение this
используется в this% ii = old% ii
, оно фактически не существует и используется нулевой указатель.Но я согласен с тем, что сообщение об ошибке Intel сбивает с толку или даже неверно.
Автоматическое левостороннее (пере) распределение применяется только для внутренних назначений, а не для определенных пользователем.В определенных пользователем вы должны запрограммировать себя точное поведение.И вы ничего не указали для нераспределенных левых частей.
Это работает для меня:
type T_TEST
integer :: ii
end type
interface assignment(=)
procedure copy
end interface
subroutine copy(this, old )
class(t_test), allocatable, intent(out) ::this
type(t_test), intent(in) :: old
if (.not.allocated(this)) allocate(this)
this% ii = old% ii
end subroutine
Или вы можете просто выделить объект первым (, это то, что ябудет делать здесь, потому что gfortran, похоже, не нравится общее разрешение на основе выделяемого атрибута - функции F08.
allocate(tt)
tt = t_test( 100 )
Кажется, что вы думаете, что только потому, что конструктор имеет егопеременная результата «помечена» allocatable
, она выделит вам левую часть задания.Это не так .Единственное, что он делает, это то, что он выделяет свой собственный результат как временную переменную.Этот результат затем присваивается в tt = t_test()
, а затем автоматически освобождается.
Помните, что переменная результата не такая же, как левая часть присвоения.Результат может использоваться в выражении разных типов, а не только в присваивании.Это может быть передано подпрограмме, это может быть использовано в арифметическом выражении, оно может быть напечатано ...
Ваш конструктор может быть просто
function init( size )
integer, intent(in) :: size
type(t_test) :: init
init% ii = size
end function
, и результат будет точнотот же самый.Нет причин делать это размещаемым, это только усложняет, но не меняет результат ни в малейшей степени.
Может быть, то, что вы пытаетесь следовать некоторым принципам C ++ RAII, но помните, C ++ просто не Fortran.