- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My program was compiling and running correctly. However, I was not getting a warning or error for situations in which I had an argument mismatch:
call foo ()
subroutine foo (x1)
I tracked down that I needed gen-interfaces and interfaces flags turned on.
I am now getting:
Error1 Error: The type of the actual argument differs from the type of the dummy argument. [KSLICE]
in situations where I don't think I should. It appears to happen because I have derived data type definitions in include files.
The following compiles:
subroutine check
C
INCLUDE 'constant.i'
c
TYPE KSLICE_STRUC
C
C !NSTA_MAX is an integer parameter defined in constant.i
c
REAL STA(NSTA_MAX)
C
C
END TYPE
C
TYPE (KSLICE_STRUC) KSLICE
call check_kslice (KSLICE)
subroutine check_kslice (KSLICE)
C
INCLUDE 'constant.i'
C
TYPE KSLICE_STRUC
C
C
REAL STA(NSTA_MAX)
C
C
END TYPE
C
TYPE (KSLICE_STRUC) KSLICE
However, when I move the definition of the derived type KSLICE into the include file kslice.i, the following does not:
subroutine check
C
INCLUDE 'constant.i'
INCLUDE 'kslice.i'
C
TYPE (KSLICE_STRUC) KSLICE
call check_kslice (KSLICE)
subroutine check_kslice (KSLICE)
C
INCLUDE 'constant.i'
INCLUDE 'kslice.i'
C
TYPE (KSLICE_STRUC) KSLICE
I get the Error: The type of the actual argument differs from...
If I turn gen-interfaces back off everything seems to work again. I would like to get an argument mismatch error when I actually have one. However, I'm not going to take the derived type definitions out of the include files (that would take a long time and cause more bugs than it would fix).
Any suggestions or help would be appreciated.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you think there is still a problem here, please create a complete test case and attach it (or a ZIP of the files) to an Intel Premier Support issue and we'll be glad to take a look.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Could you clarify this?
Are you saying if the user's declaration of KSLICE_STRUC is in an include file used by both (multiple) subroutines and/or functions that this is interpreted as the same declaration. However if the same text of the include file were pastedinline in each subroutine/function that the structures, though named and declared the same, are considered different types?
This seems somewhat odd and potentially un-useful (taking liberties with language). Consider having a .DLL or .LIB with a printed document describing the types used in the interfaces. Then wouldn't the rule lead to the user not being able to write their own include file for the interfaces? Seems somewhat useless to me.
I can see the use of this behavior if the structure were declared in a module, i.e. scoped to the module, but scoping it to a named include file (or perhaps named, versioned, tagged, ...) seems a bit restrictive.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The onlu way that they can be considered the same declaration is if there is one instance of the declaration in a module that is used to declare both the actual argument in the caller and the dummy argument in the subroutine, or a single declaration is host-associated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Then (according to the twodifferentbut same named instances)how would you declare an interface to a library function/subroutinetaking a derived type argument and where you do not have the module defining the interface as was used in creating the library?
Yes, this is a symantics issue. For what its worth you seemed to be focused on "declaration", the original poster as well as myself are focusing on "defined". A "declaration" instantiates a variable of a "defined" (pre-defined or user defined) type. The argument matching is on "defined" type as per "declarations" of the dummy variables.
With the above said, it would be nice to have a clarification on this issue as to a) what the compiler does, b) what the F90/F95/F?? specifies, c) what is generally required by the user community.
Exampe situation:
! modFooInterface.f90
module modFooInterface
type myType
...
end type myType
interface
subroutine Foo(aFoo)
use modFooInterface
type(myFoo) :: aFoo
end subroutine Foo
end interface
! end of file modFooInterface.F90
! modFoo.F90
module modFoo
...
contains
subroutine Foo(aFoo)
use modFooInterface
type(myFoo) :: aFoo
...
end subroutine Foo
end modFoo
------------
Assume modFoo.F90 is compiled into a library.
If the user were to write a program and have "use modFooInterface" in program then both the user program and the library (modFoo.F90) will have used the same module used in defining, and declaring the argument to subroutine Foo (modFooInterface.MOD). No confusion here.
What I interpret as your statements is I cannot call Foo from a program that uses an alternate method to define type myFoo and the interface to Foo in modFoo.lib. i.e. I read your statements as I cannot call modFoo::Foo without a "use modFooInterface".
If this is so then how can you create a module which calls say kernel32? MS is not using your .mod files.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What you cannot do is, in Fortran routine SUB1 declare a derived type which you use for an argument and then have another declaration of that type in SUB2 which calls SUB1 (assuming that SUB2 can see the interface for SUB1.) This is what the OP's code does and it's not legal.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Your second paragraph is quite clear, although the mechanics used by the compiler is not clear. Is it by name decoration of the type (e.g. SUB1_mp_MYTYPE).
So if SUB2 needs to call SUB1 with a derived typethen the proper method is to write a commoninclude file (or module) that both use. SUB1_SUB2.i and thus both generate SUB1_SUB2_mp_MYTYPE or whatever the case may be.
Filename decoration does not get around different files - same name. Or same file - different conditional comilation paths. (same for .MOD files). Or same file different revisions.
Is it that what you refered to in the first paragraph works because the external subroutine is defined in the interface block along with the type and the external subroutine is generally ALIASED?
Conversely is therea potential problem for the unwitting user if the external subroutine (in .LIB) was compiled with IVF _without_ ALIAS and using different module or include file?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Name decoration is not involved. A type declaration is something that is visible to the compiler only. When you have a type declared in the module, the compiled .mod has the compiler internal representation of the type. The compiler keeps track of the type MYTYPE declared in module MYMOD, but there's no user-visible name decoration that is applied.
The problem under discussion is when there is a call to a routine for which an explicit interface is visible so the compiler is required to check the arguments. For each argument in the call, it must ensure that it matches in Type, Kind and Rank (often abbreviated TKR) with the dummy argument in the visible explicit interface. It's obvious that, say, an INTEGER actual argument does not match a CHARACTER dummy argument. But what if the actual argument and dummy argument are variables of type MYTYPE? What are the rules for matching these?
The rule is that both items must have been declared with the same type, and "same" means exactly that - a single declaration used by both. It is not good enough that it's the same name with the same components of the same component types. Once the compiler has determined that both entities are of the same type, then it allows compilation to proceed. If not, it gives an error.
Of course, if the compiler cannot see an explicit interface, then it has no way of checking.
I'm afraid you lost me on the last part of your question. There is nothing in name decoration that is affected by where a type is declared. There IS name decoration for routines which are contained in a module - just having an interface in the module doesn't count since an INTERFACE block is always for an "external" procedure.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page