Reputation: 45
I'm trying to make a custom data-type constructor by overloading the type name. However, when making the call, the default constructor gets called instead. I cannot understand what I am doing wrong.
Here's a code snippet that has the problem.
module test
type, public :: foo
character(512) :: str
logical :: flag1
logical :: flag2
end type
! overload foo data-type
interface foo
module procedure make_foo
end interface
contains
! custom constructor
function make_foo(str, flag1) result(self)
implicit none
type(foo) :: self
character(512), intent(in) :: str
logical, intent(in), optional :: flag1
self % str = str ! this needs to be passed
self % flag1 = .false. ! this needs to be optional, and is false by default
if (present(flag1)) self % flag1 = flag1
self % flag2 = .false. ! this cannot be passed and is always false by default
end function
end module
program tmp
use test
implicit none
type(foo) :: a
a = foo("hello") ! error here
end program
I want to have a custom constructor that requires str
to be passed, that allows for the optional specification of flag1
and that deals with flag2
always by itself.
When testing the data-type using its constructor, it uses the default constructor and it complains for missing components.
No initializer for component 'flag1' given in the structure constructor at (1)
I am using gfortran 10.2.0
Upvotes: 3
Views: 196
Reputation: 32366
The assignment statement
a = foo("hello")
is taken to be a reference to the generic foo
if possible, and a reference to the default structure constructor for the type foo
otherwise.
In the case here, the generic foo
has one specific interface: make_foo
. For reference to the generic foo
we need foo("hello")
to be consistent with make_foo
.
The dummy argument str
is declared as character(512)
and so we are not allowed to reference it with actual argument the literal constant "Hello"
: that constant is (much) too short.1
The compiler falls back to the default structure constructor, and then (rightly) complains that there are components without default initialization which haven't been given values.
This reference can be fixed in one of two ways:
str
shorter, or better, assumed lengthTo address a concern about assumed length str
: even if it's length 5, it still can be used in the assignment self%str = str
as it will be padded with blanks at the end to make its length up to the 512 of self%str
.
Whether that's strictly sufficient to deem the reference "inconsistent" is irrelevant: in trying to do this one doesn't have a Fortran program, so one can't demand the compiler tries that reference.
Upvotes: 3