- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This isn't a bug as such, but perhaps a feature request.
I have some code that I am maintaining and enhancing, and in this instance I am annotating it for offload programming on the Xeon Phi. Wishing to keep as much of the annotations out of the source code as possible, I place the !DIR$ ATTRIBUTES OFFLOAD : mic :: foobar into an interface module. This works quite well provided you do not do something like the following:
subroutine FooBar(A,B,C) use MyInterfaces, ONLY: SomeOtherRoutine
Well, this eliminates considering the interface for FooBar itself (assuming it is contained in the module, it was).
This was definitely my programming error, however, on the other hand, the compiler could implicitly (and conditionally) ONLY-fy interfaces to self. Or, note that self interface was inside the module and issue a warning to the potential for error.
I had a significant amount of issues in trying to figure this out because the code was inside a DLL called from a managed C# forms application. Error diagnostics (defining H_TRACE in this case), was not documented in the offload, and the fact that the app had no console, using it placed the error messaged into the bit bucket. This error was not detectible at compile or link time, rather it was a runtime error only inside the MIC offload. IOW the subroutine was not found in the dynamic load library generated.
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand correctly a "warn unused" would apply? There was a feature request for USE xxx, Only: yyyy where yyyy is not actually used to generate a warning. This feature was added to 15.x but doesn't work in many instances. I haven't seen that DPD closed as yet....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interface-to-self has been hotly debated amongst the standards committee members, but the majority opinion was not to go there. The suggestion of automatically excluding interface-to-self is interesting, but I don't see the committee going for that.
As for directives that apply to a routine implementation, our rule is that they have to appear in the routine itself so that the compiler can change its behavior accordingly (since interface-to-self is prohibited.)
The compiler DOES complain about interface-to-self if you ask for standards checking:
C:\Projects>ifort -c -stand t.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 16.0.1.146 Build 20151021 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. t.f90(9): warning #7925: An interface-block in a subprogram that contains an int erface-body for a procedure defined by that subprogram is non-standard. [FOO] subroutine foo (arg) -----------^
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm... then a module containing only interfaces cannot be uses in routines using the interface module to access other routines defined in the interface module.... without explicitly listing those routines with an ONLY clause to the USE statement. In this case an EXCLUDE would be handy to expressly exclude your own interface.
USE InterfaceModule, EXCLUDE: Myself ! *** EXCLUDE not valid
Note then, that you cannot then use the interface module to assure that the interface in the interface module is consistent with the interface of the actual routine. This goes against the intention of -warn:interfaces.
While one might argue that any well written module will have a CONTAINS section containing the actual routine, as opposed to a module containing just the interface, the reality (in practice) is you often have situations where modules A, B and C need to be aware of each other. Using a CONTAINS section then causes circular references (when editing routines), whereas using INTERFACE only modules does not.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
reading this thread is both interesting and challenging
Merry Thanksgiving Day
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually, if you use /warn:interface we can (sometimes) detect an inconsistency and warn you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>if you use /warn:interface we can (sometimes) detect an inconsistency and warn you.
But then by permitting self, you (always) detect inconsistencies.
Note 2
Assuming a well respected routine contains multiple USE of other vendors modules, which may contain USE of there modules containing interfaces... to your routine!!!. By permitting "self" you also enforce a consistency check of all such USE's and avoid interface conflicts.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
>>if you use /warn:interface we can (sometimes) detect an inconsistency and warn you.
But then by permitting self, you (always) detect inconsistencies.
Note 2
Assuming a well respected routine contains multiple USE of other vendors modules, which may contain USE of there modules containing interfaces... to your routine!!!. By permitting "self" you also enforce a consistency check of all such USE's and avoid interface conflicts.
Jim Dempsey
It'll help if such a discussion can be based on a concrete, workable example (and given Jim's experience, shouldn't take long to present an actual scenario, especially to avoid any misunderstanding among other readers of the issue at hand).
For I think the standard Fortran solution for Jim would be to use SUBMODULEs - given a concrete case in front of us, we would be able to try it out and illustrate it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Use of sub-modules may resolve the circular reference issue... at the expense of a major overhaul of the code. This is not the subject of the discussion, but rather one such situation.
Providing self-reference with respect to interface modules is important to assure that the routine itself is consistent with the interface you provide.
It is not unreasonable for a software vendor to supply binary files only (.obj, .lib, .dll), together with a module that defines the interfaces to their code. What is the purpose of having a standard that inhibits verification that your interfaces are consistent with your actual code??
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
Use of sub-modules may resolve the circular reference issue... at the expense of a major overhaul of the code. This is not the subject of the discussion, but rather one such situation.
Providing self-reference with respect to interface modules is important to assure that the routine itself is consistent with the interface you provide.
It is not unreasonable for a software vendor to supply binary files only (.obj, .lib, .dll), together with a module that defines the interfaces to their code. What is the purpose of having a standard that inhibits verification that your interfaces are consistent with your actual code??
Jim Dempsey
Jim,
I agree with you totally. See this thread, especially Message #30.
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/507087
And there have been other threads too on this forum as well as others where I have tried to engage experts-that-may-be in discussion on changes in the Fortran standard that would provide an "interface to self" kind of feature. But as Steve said, I get swatted away by the usual suspects. It appears the standard body has pretty much settled on SUBMODULEs and that will be your path of least resistance if you're looking for a "standard Fortran" solution. You may want to look into it, for chances are you will be able to figure out options (say using automated/semi-automated scripts, etc.) to achieve the code overhaul without much effort and pain:
module myinterfaces implicit none interface module subroutine foo() end subroutine foo module subroutine bar(i) integer, intent(in) :: i end subroutine bar end interface end module myinterfaces
submodule(myinterfaces) sm1 contains module subroutine foo() call bar("Hello World!") return end subroutine foo end submodule sm1
submodule(myinterfaces) sm2 contains module subroutine bar(i) integer, intent(in) :: i print *, " In bar: i = ", i return end subroutine bar end submodule sm2
Upon compilation, the following error is raised in foo about the mismatch in interface with bar, thereby showing one of the benefits of SUBMODULEs:
------ Build started: Project: p, Configuration: Release|x64 ------ Compiling with Intel(R) Visual Fortran Compiler 16.0 [Intel(R) 64]... m.f90 m.f90(24): error #6633: The type of the actual argument differs from the type of the dummy argument. ['Hello World!'] compilation aborted for m.f90 (code 1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey, interface to self has always been allowed and is useful for checking that a procedure matches its interface body.
module M implicit none interface subroutine S(x) implicit none real x end subroutine S end interface end module M program P use M implicit none real y call S(y) write(*,*) 'y = ', y end program P subroutine S(x) use M use M, only: T => S implicit none real x if(.FALSE.) then BLOCK procedure(T), pointer :: U => S END BLOCK end if x = 257 end subroutine S
BTW, has this bug been fixed in Update 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In #11, there are two interfaces, from two separate definitions, for S accessible inside the scope of the subroutine S. That's non-conforming.
There is a distinction between the interface as a thing, and the identifier used to refer to that thing. The use renaming just changes the latter.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, there is no nonconformance. In module M, there are only instructions on how a user of the module is to invoke a specific procedure and how the linker is to search for the procedure that satisfies that interface. It's no problem that subroutine S uses that interface. What if we had named it subroutine R instead? Surely that would be OK. Then the *.DEF file makes subroutine R available to the linker under the name S. Still OK, right? What's the difference that we named the subroutine S directly?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Discussion of linkers and DEF files gets into implementation details, beyond what the standard covers.
The standard just says you cannot have more than one explicit specific interface for a procedure accessible in a scoping unit.
(You are permitted to have multiple names for the one interface definition in the one scope, but there are two separate definitions in #11.)
I could come up with plenty of examples of where non-conforming code ends up "working", perhaps even relatively reliably, but that doesn't change the non-conforming nature of the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You seem to be conflating the interface and the procedure itself. All the pieces are OK in themselves, it's just after they are all compiled, if the user chooses to link them together in a certain way, that the program might be claimed to be nonconforming. But the standard doesn't really go into choices at the linking stage of that sort -- does it even mention linking?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I couldn't find the passage in the standard where it says that you cannot have more than one explicit specific interface for a procedure accessible in a scoping unit. Can you point me to it so that it's possible to discuss what it means in the context of the present discussion?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the subprogram that defines the external procedure S, there is an explicit specific interface for the external procedure S, that is specified by the SUBROUTINE statement and the associated specification statements of the subprogram. That is explicit specific interface #1.
The module has a public entity that is also an explicit interface for S, specified by the SUBROUTINE statement and specification part of the interface body. That public entity is then made accessible inside the scope of the subprogram by a USE statement. The rename facility of the USE statement changes the name by which the interface can be accessed, but it is still an explicit specific interface for S - as S is the name that appeared in the interface body. That is explicit specific interface #2.
"A procedure shall not have more than one explicit specific interface in a given scoping unit, except that if the interface is accessed by use association, there may be more than one local name for the procedure. If a procedure is accessed by use association, each access shall be to the same procedure declaration or definition."
One of the interfaces is not accessed by use association, and you have two definitions of the interface. The source code is non-conforming. How the user compiles or links things doesn't change that - it is a property of the source code comprising module M and subroutine subprogram S.
Whether the restriction on interface to self is reasonable or not in the first place is also not relevant. I haven't thought about this enough to come up with a view on its reasonableness, but I can understand why there would be some resistance to relaxing the restriction from a conceptual point of view - you would be permitting definition of the one entity from two completely separate sections of Fortran source, which I suspect would be a rather novel thing for the language (are there other examples?).
I have half finished (and fully buggy!) tools that do full program semantic analysis of Fortran source, one of the aims of which was to identify errors such as a mismatch between an external procedure definition and any interface bodies. I know I am not the only one to head down this path, and ifort clearly already has material capability in this area. I think the application of such tools to the problem that Jim describes (beyond the use of submodules, which do significantly reduce the requirement for external procedures) to be more efficacious than the implied alternative of modifying the language, all processors and all relevant Fortran source code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Repeat Offender wrote:
Hey, interface to self has always been allowed and is useful for checking that a procedure matches its interface body...
Interesting idea, the following simplified version compiles fine with gfortran (GCC 6.0 development version) but Intel Fortran raises error #6592 and #6973 respectively. Not sure if the code is standard-conforming.
module myinterfaces implicit none interface subroutine sub() end subroutine sub end interface public :: sub end module myinterfaces subroutine sub() use myinterfaces, only : Isub => sub procedure(Isub), pointer :: foo_ptr => sub return end subroutine sub
Keeping in mind the goal here is to do interface checking, I suppose one would consider wrapping the procedure pointer line on 20 with some preprocessor/compiler directive to accomplish the check only until the interface is validated.
However, given the supposed constraints in the standard with procedure pointers (e.g., elemental procedures are not allowed), this approach has limitations, even if it were to be standard-conforming.
And to add, if an interface mismatch is introduced, gfortran flags it as shown below:
module myinterfaces implicit none interface subroutine sub() end subroutine sub end interface public :: sub end module myinterfaces subroutine sub(s) use myinterfaces, only : Isub => sub character(len=*), intent(in) :: s procedure(Isub), pointer :: foo_ptr => sub return end subroutine sub
m.f90:22:45: procedure(Isub), pointer :: foo_ptr => sub 1 Error: Interface mismatch in procedure pointer assignment at (1): 'sub' has the wrong number of arguments
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ianh wrote:
In #11, there are two interfaces, from two separate definitions, for S accessible inside the scope of the subroutine S. That's non-conforming.
There is a distinction between the interface as a thing, and the identifier used to refer to that thing. The use renaming just changes the latter.
Yes, IanH, there are two interfaces:
That inside the use, and
That of "self"
The whole point of this discussion is by permitting "self" in the USE'd module, the compiler can verify the USE's interface against "self". Consider this as an automated verification that you, or the next person touching your code, does not muck up anything else, by making a seemingly benign change.
Note, if you really do .NOT. want the interface checked (assuming you want the actual interface to differ from the USED interface) you have a means to do this using ONLY on the other parts of interest in the module.
I think the whole standards committee issue with permitting this that there compiler may have had issues with various attributes applied to the arguments. In earlier versions of IVF, where you could self reference, it would at times error out on some attribute combinations (even on a copy and paste of the actual code). My guess it they do not want to be required to fix this.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the code in #18 is conforming. The error message ifort gives is perplexing, to say the least. I will report this to the developers. Issue ID is DPD200379165.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I see the section quoted in the standard. I still reserve my opinion on whether it wipes out my code in Quote #11. But I found another passage in the same section:
If an external procedure does not exist in the program, an interface body for it may be used to specify an explicit specific interface but the procedure shall not be used in any other way.
So I modified my program to something which, with the above qualification, I think you might find more agreeable.
module M
implicit none
interface
subroutine S(x) bind(C,name='self1')
implicit none
real x
end subroutine S
end interface
end module M
program P
use M
implicit none
interface
subroutine R(x) bind(C,name='self2')
implicit none
real x
end subroutine R
end interface
real y
call R(y)
write(*,*) 'y = ', y
end program P
subroutine S(x) bind(C,name='self2')
use M
use M, only: T => S
implicit none
real x
if(.FALSE.) then
BLOCK
procedure(T), pointer :: U => S
END BLOCK
end if
x = 257
end subroutine S

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