Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Derived type constructor resolution

IanH
Honored Contributor III
1,220 Views
With 12.0.3, derived type structure constructor "overloads" (i.e. when you have a generic function with the same name as the derived type) don't appear to be recognised inside the module that has the relevant generic interface block. Plus if the defining module is PRIVATE by default then error 7977 strangeness happens.

DerivedTypeConstructors.f90

[plain]>ifort /check:all /warn:all DerivedTypeConstructors.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.0.3.175 Build 20110309
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

DerivedTypeConstructors.f90(53): error #6594: The rank of an element in a structure constructor differs from the rank of the component of the derived type
    a = derived_type([1, 2], 3);  PRINT "('Backwards:',I0)", a%scalar    ! #2
----------------------^
DerivedTypeConstructors.f90(55): error #8212: Omitted field is not initialized. Field initialization missing:   [SCALAR]
    a = derived_type();           PRINT "('None:',I0)", a%scalar         ! #3
^
compilation aborted for DerivedTypeConstructors.f90 (code 1)[/plain]

Or with the modules default accessibility PRIVATE and the otherwise offending lines commented out:

[plain]>ifort /check:all /warn:all DerivedTypeConstructors.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.0.3.175 Build 20110309
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

DerivedTypeConstructors.f90: error #7977: The type of the function reference does not match the type of the function definition.   [MYMODULE^DERIVED_TYPE_FORWARDS]
DerivedTypeConstructors.f90: error #7977: The type of the function reference does not match the type of the function definition.   [MYMODULE^DERIVED_TYPE_BACKWARDS]
DerivedTypeConstructors.f90: error #7977: The type of the function reference does not match the type of the function definition.   [MYMODULE^DERIVED_TYPE_NONE]
compilation aborted for DerivedTypeConstructors.f90 (code 1)[/plain]
0 Kudos
8 Replies
Steven_L_Intel1
Employee
1,220 Views
I am looking at this now. There may be more than one issue here.

I did determine that your program is non-standard because the inclusion of the specific routine derived_type_forwards and use of the first constructor violates the following constraint (quoting F2008 here):

C496 (R455) If a derived-type-spec is a type name that is the same as a generic name, the component-spec-list shall not be a valid actual-arg-spec-list for a function reference that is resolvable as a generic reference to that name (12.5.5.2).

Bug 1: The compiler does not catch this.

This constraint is really weird, because it says that you can declare the specific function but you can't use it (at least not with the generic name.) If you wanted to do this you'd have to do something ugly such as adding another component to the derived type that was unused.

I will look at the other issues soon.
0 Kudos
IanH
Honored Contributor III
1,220 Views
Ah... I'd missed that constraint - it was actually the backwards constructor that was tripping up in the original code and I added the other two as part of testing. I was operating under the erroneous impression that the generic function reference was matched in preference to the out-of-the-box constructor. That constraint seems a bit silly to me. I'll pretend it was note 4.58's fault for me going astray.

Mind you, if you have one argument keyword in there, then that constraint isn't violated, so I respectfully submit...

DerivedTypeConstructors2.f90
0 Kudos
Steven_L_Intel1
Employee
1,220 Views
Yes, that constraint is easy to overlook. I filed issue DPD200169528 about the missing error, the "forgetfulness" in PROC, and the internal compiler error I got when I removed some code (possibly related to the other error you saw).

Your new file is just a variant on the "forgetfulness" issue.
0 Kudos
IanH
Honored Contributor III
1,220 Views
That constraint (C496 in F2008) has been bugging me. It seems silly, but...

I thought the way the standard worked, the constraint only applies to the syntax rule that it is associated with (R455). Now, somewhere else I'm sure I've read in the standard that if something that looks like a structure constructor can be interpreted as a generic function reference, then it is a function reference (Note 4.58 supports that, but I don't know where the normative bit is). In that case, the syntax rule isn't relevant because the bit of syntax that you are looking at isn't a structure constructor. If the syntax rule isn't relevant then the constraint isn't relevant?

So why have the constraint? Well, it's dawned upon me that there are places where what in isolation looks like a structure constructor or generic function reference can only be a structure constructor by the syntax rules - for example the constants in data statements (R542, there might be others). Then the constraint makes sense in that specific place - you can't try and confuse the compiler by getting it to stick a function reference in where a constant should go (or to construct an object without using the constructor that the programmer has explicitly gone to all the trouble of providing).

So what the constraint means is you can have a specific function in a generic that looks exactly like a structure constructor and you can call that function to construct the type in an expression, but you then cannot go and use the actual structure constructor for that type in a data statement.

Thoughts?
0 Kudos
Steven_L_Intel1
Employee
1,220 Views
Actually, in a DATA statement such a reference can only be a structure constructor, since only initialization expressions are valid there. The constraint is where it is because it is tied to the syntax of structure constructors. The Fortran standard tries very hard to say things once only, but sometimes it can be maddening figuring out WHICH one place that is.

What I don't understand is why the standard didn't just say that if the use can be resolved as a generic reference then that's what it is. There are other places in the standard with similar wording, where in the case of ambiguity a precedence order is established. I asked our primary standards rep about this and he recalled many days of argument over this particular issue, but couldn't tell me why a simple precedence rule wasn't established.
0 Kudos
Steven_L_Intel1
Employee
1,220 Views

It was clarified for me by the editor of the standard that:

C496 (R455) If derived-type-spec is a type name that is the same as a generic name, the component-spec-list shall not be a valid actual-arg-spec-list for a function reference that is resolvable as a generic reference to that name (12.5.5.2).

is intended to resolve the ambiguity when something could be either a structure constructor or a generic function reference. This constraint is not a restriction on the program but rather on the parser, with note 4.58:

The form 'name(...)' is interpreted as a generic function-reference if possible; it is interpreted as a structure- constructor only if it cannot be interpreted as a generic function-reference.

indicating that in such a case, it is to be interpreted as a generic function reference.

I have informed the developers of this.

0 Kudos
Steven_L_Intel1
Employee
1,220 Views
The compiler has been fixed to select the generic interface if it also looks like a type constructor. The fix will appear in an update later this year (October or thereabouts.)
0 Kudos
Steven_L_Intel1
Employee
1,220 Views
The fix is included in Composer XE 2011 Update 7, available now. Note that we still require "MODULE" in "MODULE PROCEDURE" - this restriction will be lifted in a future version.
0 Kudos
Reply