- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the code below, which has nested derived-types with default initialisation in it.
module mod implicit none private type, public :: a integer :: i = 5 end type a type, public :: b type(a) :: n end type b interface b module procedure create_b end interface b contains function create_b() result(x) type(b) :: x x%n = a() end function create_b end module mod program definit use mod implicit none type(b) :: u print *, same_type_as(u, b()) end program definit
I have several issues with the code and ifort (beta release):
(1) Without the constructor create_b and "interface b", ifort complains that
definit.f90(25): error #8212: Omitted field is not initialized. Field initialization missing:
print *, same_type_as(u, b())
^
I have reported this as a bug, but was told that this is not legal fortran. But I think default initialisation in nested derived-types is pretty clear (at least if I read Metcalf "7.5.4 Default initialisation of components", edition from 2011, correctly). Please correct me if I am wrong.
(2) As a work-around I tried to add explicit default initialisation
type, public :: b type(a) :: n = a() end type b
which works fine. And I also tried adding create_b (where I explicitly need to initialise component n with x%n = a(), probably the same problem mentioned in (1)). But now I get
definit.f90(36): error #8250: The argument to the SAME_TYPE_AS intrinsic function must be an object of extensible type.
print *, same_type_as(u, b())
Why are u and b() (without the create_b interface) accepted, but not type(b) as a function result of create_b? In general type(b) is an extensible type and all three arguments should be accepted by same_type_as, right?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interesting piece of code: It is clear that your code doesn't work without the interface and the create_b procedure, because the proper structure constructor would be b(a()) instead of b(). The type a has to be created first, before you are using a structure constructor for b.
The modified code with the interface compiles with NAG, PGI and gfortran, and is rejected by ifort. The F2018 standard in 16.9.165.3 states that same_type_as as an inquiry function has two arguments which shall be objects of extensible type or [unlimited polymorphic, doesn't apply]. An extensible type is one that may be extended using the EXTENDS clause (definition 3.147.6), which applies to both your types a and b. It explicitly applies to u which is of type b, and accepted by ifort, but also to the function result of the procedure create_b. I consider this second thing (not the first one that you sent in) a compiler bug from ifort which you might check with the Ifort support.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Juergen R. wrote:Interesting piece of code: It is clear that your code doesn't work without the interface and the create_b procedure, because the proper structure constructor would be b(a()) instead of b(). The type a has to be created first, before you are using a structure constructor for b.
I do not quite understand this. According to Metcalf, all components are initialised (there is an example which is similar to mine).
A declaration
type(b) :: x
should initialise all components, no need to write x%n = a() (as requested by the compiler for the create_b function, this is actually a third issue I have). So why should I give a default value by b(a()) if component n already has default initialisation? Moreover, if I replace component "type(a) :: n", with "integer :: k =3" or something, then I can just write b() instead of b(3). I find this inconsistent and confusing. Is this really fortran standard? I am not able to find anything, except that all should be default initialised.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The F2008 standard says in 7.5.4.6.7 on default initialization for components:
A subcomponent (9.4.2) is default-initialized if the type of the object of which it is a component specifies default initialization for that component, and the subcomponent is not a subobject of an object that is default-initialized or explicitly initialized.
Your subcomponent n of type a is the subcomponent of type b which is default initialized because you are using a structure constructor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Juergen R. wrote:The F2008 standard says in 7.5.4.6.7 on default initialization for components:
A subcomponent (9.4.2) is default-initialized if the type of the object of which it is a component specifies default initialization for that component, and the subcomponent is not a subobject of an object that is default-initialized or explicitly initialized.
Your subcomponent n of type a is the subcomponent of type b which is default initialized because you are using a structure constructor.
I already found this section in the standard, and I understand that for b() everything should be initialised. I feel pretty dumb, but I just do not understand this?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page