Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26749 Discussions

Extensible type restriction in same_type_as

Martin1
New Contributor I
99 Views

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?

 

0 Kudos
4 Replies
Juergen_R_R
Valued Contributor I
99 Views

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.

Martin1
New Contributor I
99 Views

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.

 

Juergen_R_R
Valued Contributor I
99 Views

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.

Martin1
New Contributor I
99 Views

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?

Reply