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

derived type as a function result

Robert_van_Amerongen
New Contributor III
493 Views
I have found a problem when a function is of a derived type. I have isolated the problem and added it below. Running the command " ifort /warn / traceback filename " the compiler produces error #7977 complaining the the function reference not being the same as the function type. This problem is caused by the compiler that produces an interface for that particular function and adds a result variable to the function definition.
If I compile with the addition of "/nogen-interfaces" in the command linethere is no problem at all!
What is going on here? The construction that I use is completely legal (Metcalf pag. 80) as long as the function is non-recursive. I did not encounter a similar problem with a function that has a scalar variable as a function result.

The example:

MODULE ctf_mod

TYPE my_type

INTEGER :: i, j

END TYPE my_type

END MODULE ctf_mod

!

PROGRAM ctf

USE ctf_mod

IMPLICIT none

!

TYPE(my_type) :: type_function

TYPE(my_type) :: type_result

!

type_result = type_function(3,8) ! the problem line

write(*,*) 'result:', type_result

STOP

END

!

TYPE(my_type) FUNCTION type_function(k,l)

USE ctf_mod

IMPLICIT none

INTEGER,INTENT(in) :: k,l

type_function%i=k

type_function%j=l

RETURN

END

0 Kudos
12 Replies
Steven_L_Intel1
Employee
493 Views
Robert,

This issue has been previously reported and is our issue ID DPD200157843. It is not yet fixed. Thanks for the report.
0 Kudos
jimdempseyatthecove
Honored Contributor III
493 Views

What happens if you explicitly add your own interface?

MODULE ctf_mod
TYPE my_type
INTEGER :: i, j
END TYPE my_type
END MODULE ctf_mod

!

PROGRAM ctf

USE ctf_mod

! VVV add this VVV

INTERFACE
TYPE(my_type) FUNCTION type_function(k,l)
USE ctf_mod
IMPLICIT none
INTEGER,INTENT(in) :: k,l
END FUNCTION type_function
END INTERFACE
! ^^^ end add this ^^^

IMPLICIT none

! comment/remove this

! TYPE(my_type) :: type_function

TYPE(my_type) :: type_result

!

type_result = type_function(3,8) ! the problem line

write(*,*) 'result:', type_result

STOP

END

!

TYPE(my_type) FUNCTION type_function(k,l)

USE ctf_mod

IMPLICIT none

INTEGER,INTENT(in) :: k,l

type_function%i=k

type_function%j=l

RETURN

END

0 Kudos
Steven_L_Intel1
Employee
493 Views
That does prevent the error.
0 Kudos
Robert_van_Amerongen
New Contributor III
493 Views
I am afraid that is not the case as I saw after doing it.Even with an explicit interface the compilation fails if there is /nogen-interfaces used in the command line. If it is present, no problem!
The point with regard to the issue raised in this thread is, of course, that I may expect the compiler to accept legal fortran constructs without any restriction.

Robert
0 Kudos
jimdempseyatthecove
Honored Contributor III
493 Views
Robert,

This seems to contradict Steve's observatons.
I am also confused at your statement "/nogen-interfaces"
as opposed to "no /gen-interfaces", or "without /gen-interfaces option"
Are you entering this (/nogen-interfaces) by hand (in additional command line options)?

Note, it is the "/warn:interfaces" that compares agains interface files of defined file name conventions.
Check to see if compiling without /geninterfaces but with /warn:interfaces .AND. out of date interface files from prior compilation (or hand written interface files). The error you are observing appears to be one of conflicting interfaces.

Jim
0 Kudos
Robert_van_Amerongen
New Contributor III
493 Views
Jim,

I am working with the command line, so every part is written by hand. From the ifort /help I found, among other things, the /nogen-interfaces option. I did never use /gen-interfaces. Why should I do that! The Fortran example does not require an explicit interface so I did neitherwrite it my self nor asks the compiler to do that for me.

I have run the program with several different command lines.
Everything works fine with
ifort /free /extfor:f03 ctf.f03
ifort /free /extfor:f03 /nogen-interfaces ctf.f03
but problems arise with:
ifort /free /extfor:f03 /warn:all ctf.f03
ifort /free /extfor:f03 /warn:all /nogen-interfaces ctf.f03
ifort /free /extfor:f03 /warn:interfaces ctf.f03

So, if the compiler is sopriggish to make interfaces, it would be nice if that are the correct ones! And that is not the case.

Robert
0 Kudos
jimdempseyatthecove
Honored Contributor III
493 Views
/nogen-interfaces would be used when the default options include /gen-interfaces. There is likely a config file, or environment variable that is used to specify the default options.

In your situation, it looks as if the default options omit /gen-interfaces (which is fine), therefore /nogen-interfaces essentially does nothing. And therefore

ifort /free /extfor:f03 ctf.f03
ifort /free /extfor:f03 /nogen-interfaces ctf.f03

are equivelent

/warn:all includes /warn:interfaces

therefore

ifort /free /extfor:f03 /warn:all ctf.f03
ifort /free /extfor:f03 /warn:all /nogen-interfaces ctf.f03
ifort /free /extfor:f03 /warn:interfaces ctf.f03

are equivelent (with respect to /warn:interfaces)

The "problem" is the /warn:interfaces (/warn:all) is requesting that the interfaces of the functions and subroutines are to be provided and compared with those used. In your case your code has

(no explicit interface declared in function/subroutine where call is made)
.or.
(interface not declared in module USE'd in function/subroutine where call is made)
.or.
(function having interface not declared in the same source file in a manner such that it isa forward/unknown reference)


The above essentialymeans the compiler does not know the interface at the point of use of functionand with /warn:interfaces enabled (/warn:all) it is informing you that it does not know the interface.

Add the interface

You might also try

/warn:all /nowarn:interfaces

*** However ***

Doing so, omits checking interfaces which is an important diagnostic.

Jim Dempsey
0 Kudos
IanH
Honored Contributor II
493 Views
Apologies - I'm just repeating what has already been said - but to remove my confusion, here's my understanding with 11.1.065:

  • There's a known bug with interface checking of external function subprograms that return derived types.
  • /warn:all includes /warn:interfaces, which as of 11.1 includes /gen-interfaces. So if you have specified /warn:interfaces (or /warn:all) you have implicitly been asking for the __genmod files to be created. If you don't want them, then you need to explicitly add /nogen-interfaces.
  • One the xxx__genmod files are there, they will be picked up by /warn:interfaces on any subsequent compiles, even if you later specify /nogen-interfaces. If you don't want them used you need to manually blow them away.
  • Having an explicit interface block in the main program for the external function subprogram makes no difference (is this a different bug?), the interface checking still trips up if /warn:interfaces is on and a xxx__genmod.mod file for the external function subprogram exists.
The results listed in post #6 could be consistent with that, assuming you didn't blow away the xxx__genmod files in between tests. Until the bug is fixed, you either need to avoid /warn:interfaces altogether for the problematic source files (or always use it with /nogen-interfaces, which effectively nobbles it), or...

Out of curiosity - a question to the OP: why isn't type_function a module procedure?

Opining, so feel free to cut me back to size: The fortran standard may not require an explicit interface here, but the number of cases where external subprograms (i.e. not module procedures) are unavoidable under F2003 is vanishingly small - the only valid "standard" reason I can think of is that you need to call the subprogram from existing untouchable F77 code (Are there others? Some sort of compilation dependency issue? Playing games with sequence association?). That can't be your situation if you are using derived types because F77 didn't have derived types. If type_function was in a module, you'd avoid the bug, and you'd also be less likely (?) to trip up with things the multiple non-sequence derived type definition problem that is in your other post, plus you'd pick up the other benefits that come with modules. (The fact that you can compile with /warn:all and not have all your directories littered with strange looking __genmod files is enough of a justification for me...)

I'd argue that one of the reasons this bug (still) exists is that the use of external fuction subprograms with derived type result is rather uncommon.
0 Kudos
jimdempseyatthecove
Honored Contributor III
493 Views
Thanks for the reply/analysis

... /warn:interfaces, which as of 11.1 includes /gen-interfaces

IMHO that is a mistake - they should remain seperate.
With implicit /gen-interfaces the programmer would not know of a missing explicit interface that would be required in their general purpose interfaces file.

Additionaly, there should be a /use:interfaces option (implicitly set with /warn:interfaces) that uses the xxx_genmod files. This would permit you to compile _without_ the xxx_genmod files when present on disk.
This would help you catch a missing USE (general purpose interfaces file).

Jim Dempsey
0 Kudos
fritschen
Beginner
493 Views
I encountered the same problem. But not until yesterday - since I changed from XE 2011, Update 2 to XE 2011, Update 3.

Did somebody observe the same - has something changed here in Update 3?

Ralf
0 Kudos
Robert_van_Amerongen
New Contributor III
493 Views
Ralf,

I installed the update 3 recently and saw the same you saw: this (reported) problem has disappeared!

Robert van Amerongen
0 Kudos
Steven_L_Intel1
Employee
493 Views
The error reported in the original post was indeed fixed in Update 3. Ralf, are you seeing something different?
0 Kudos
Reply