- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would have thought the following is a common problem, but I did not find a satisfactory solution: Many subroutines defined for real arrays work as well for a complex array if it is interpreted as a real array of double size. For example some of our programs do this:
This actually compiles and works if callee is defined in an external subprogram, but of course it violates the standard and breaks if the gen-interfaces compiler switch is used.
Is there any "clean" solution to do this, apart from defining callee twice (once for real and once for complex arguments)? An equivalence statement is not an option as it cannot be used with dummy arguments.
I'd also like to ask the same question with regard to multi-dimensional arrays interpreted as one-dimensional. Here I could of course use the reshape intrinsic, but that implies a lot of copying and therefore cannot generally be used.
(As a side note: the gen-interfaces switch generates interfaces but no compile time error if an external statement exists; is this the intended behavior?)
[fortran]subroutine callee(arr, N)
integer, intent(in) :: N
real, dimension(1:N), intent(in) :: arr
! do stuff
end subroutine callee
subroutine caller()
complex, dimension(1:10) :: arr
! [...]
call callee(arr, 20)
end subroutine caller
[/fortran]
This actually compiles and works if callee is defined in an external subprogram, but of course it violates the standard and breaks if the gen-interfaces compiler switch is used.
Is there any "clean" solution to do this, apart from defining callee twice (once for real and once for complex arguments)? An equivalence statement is not an option as it cannot be used with dummy arguments.
I'd also like to ask the same question with regard to multi-dimensional arrays interpreted as one-dimensional. Here I could of course use the reshape intrinsic, but that implies a lot of copying and therefore cannot generally be used.
(As a side note: the gen-interfaces switch generates interfaces but no compile time error if an external statement exists; is this the intended behavior?)
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are various ways to handle this. First, Intel Fortran has an extension called the NO_ARG_CHECK attribute. When this is specified on a routine or a dummy argument, it disables compile-time checks for type, rank and kind. So you could add:
!DEC$ ATTRIBUTES NO_ARG_CHECK :: arr
in "caller" to avoid the generated interface errors.
The Fortran TRANSFER intrinsic is sort of like reinterpret_cast in that it gives you a result with the same bits, just as a different type.
You can also do something like this:
A third option is to use generic interfaces that all bind to the same routine using ALIAS.
I can't reproduce the issue you raise regarding EXTERNAL. Can you show an example?
!DEC$ ATTRIBUTES NO_ARG_CHECK :: arr
in "caller" to avoid the generated interface errors.
The Fortran TRANSFER intrinsic is sort of like reinterpret_cast in that it gives you a result with the same bits, just as a different type.
You can also do something like this:
[fortran]subroutine callee(arr, N) use iso_c_binding
integer, intent(in) :: N real, dimension(1:N), intent(in) :: arr complex, dimension(:), pointer :: p_arr call c_f_pointer (c_loc(arr), p_arr, [N/2]) ! do stuff with p_arr end subroutine callee[/fortran]
A third option is to use generic interfaces that all bind to the same routine using ALIAS.
I can't reproduce the issue you raise regarding EXTERNAL. Can you show an example?
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are various ways to handle this. First, Intel Fortran has an extension called the NO_ARG_CHECK attribute. When this is specified on a routine or a dummy argument, it disables compile-time checks for type, rank and kind. So you could add:
!DEC$ ATTRIBUTES NO_ARG_CHECK :: arr
in "caller" to avoid the generated interface errors.
The Fortran TRANSFER intrinsic is sort of like reinterpret_cast in that it gives you a result with the same bits, just as a different type.
You can also do something like this:
A third option is to use generic interfaces that all bind to the same routine using ALIAS.
I can't reproduce the issue you raise regarding EXTERNAL. Can you show an example?
!DEC$ ATTRIBUTES NO_ARG_CHECK :: arr
in "caller" to avoid the generated interface errors.
The Fortran TRANSFER intrinsic is sort of like reinterpret_cast in that it gives you a result with the same bits, just as a different type.
You can also do something like this:
[fortran]subroutine callee(arr, N) use iso_c_binding
integer, intent(in) :: N real, dimension(1:N), intent(in) :: arr complex, dimension(:), pointer :: p_arr call c_f_pointer (c_loc(arr), p_arr, [N/2]) ! do stuff with p_arr end subroutine callee[/fortran]
A third option is to use generic interfaces that all bind to the same routine using ALIAS.
I can't reproduce the issue you raise regarding EXTERNAL. Can you show an example?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot for your answer. I must admit I did not understand your third option; if I understand correctly, ALIAS creates a different name for a subroutine visible from the outside, but I do not see how this could be used to override the argument check.
As to the issue of the compiler failing to emit a warning, no wonder you could not reproduce this because it apparently only occurs if the external subroutine is not called from the main program but only in a subroutine. Minimal example:
No error is generated with Intel Fortran 10.1 for Windows and 11.1 for Linux with the command "ifort -warn all -gen-interfaces callee.f90 calltest.f90".
PS: The syntax highlighter of this forum seems to have a problem with Internet Explorer 7. The code looks okay in the edit window, but in the preview the line breaks have vanished.
As to the issue of the compiler failing to emit a warning, no wonder you could not reproduce this because it apparently only occurs if the external subroutine is not called from the main program but only in a subroutine. Minimal example:
[fortran]! calltest.f90 program calltest implicit none external callee ! if this is commented out ... ! ... or if callee() is called here the compiler notices the ! interface mismatch call main() contains subroutine main() integer, parameter :: N = 10 complex, dimension(1:N) :: arr = 0 call callee(arr, 2*N) end subroutine main end program calltest ! callee.f90 subroutine callee(arr, N) implicit none integer, intent(in) :: N real, dimension(1:N), intent(in) :: arr print *, arr end subroutine callee [/fortran]
No error is generated with Intel Fortran 10.1 for Windows and 11.1 for Linux with the command "ifort -warn all -gen-interfaces callee.f90 calltest.f90".
PS: The syntax highlighter of this forum seems to have a problem with Internet Explorer 7. The code looks okay in the edit window, but in the preview the line breaks have vanished.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The "external" issue you mention is one that has been reported before and will be fixed.
My suggestion regarding alias was a way to have two (or more) signatures for a single routine. For example:
My suggestion regarding alias was a way to have two (or more) signatures for a single routine. For example:
[fortran]interface mysub subroutine mysub_real (x) !dec$ attributes alias:"mysub_generic" :: mysub_real real, dimension(*) :: x end subroutine mysub_real subroutine mysub_complex (x) !dec$ attributes alias:"mysub_generic" :: mysub_complex complex, dimension(*) :: x end subroutine mysub_complex end interface subroutine mysub_generic (x) !dec$ attributes alias:"mysub_generic" :: mysub_generic real, dimension(*) :: x ! or whatever you want end subroutine mysub_generic [/fortran]
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page