- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a problem with the following abridged code using intel ifort and icc 10.1 compilers. The answer the program should return is
BEFORE SUB: NTYPES_F = 202
IN SUB: NTYPES_F = 202
it returns
BEFORE SUB: NTYPES_F = 202
IN SUB: NTYPES_F = 101
if I place the test_global routine before the multi_l subroutine (or take out the multi_l subroutine) it returns the correct result. Note that the program never calls the multi_l subroutine. The code works correctly using g95, gfortran, pgi, and sun compilers.
--------SOURCE--------
FORTRAN:
MODULE globmod
IMPLICIT NONE
INTEGER, DIMENSION(1:2) :: flags
INTEGER :: NTYPES_F
EQUIVALENCE(flags(2), NTYPES_F)
END MODULE globmod
MODULE F5
USE globmod
CONTAINS
SUBROUTINE multi_l()
USE iso_c_binding
IMPLICIT NONE
INTEGER(KIND=C_INT), DIMENSION(1:NTYPES_F) :: memb_map
INTEGER hdferr
INTERFACE
INTEGER FUNCTION multi_c(memb_map)
USE iso_c_binding
USE globmod
INTEGER(KIND=C_INT), DIMENSION(1:NTYPES_F) :: memb_map
END FUNCTION multi_c
END INTERFACE
memb_map = 9
hdferr = multi_c(memb_map)
END SUBROUTINE multi_l
SUBROUTINE test_global()
IMPLICIT NONE
PRINT*,'IN SUB: NTYPES_F =',NTYPES_F
END SUBROUTINE test_global
END MODULE F5
PROGRAM test
USE F5
IMPLICIT NONE
flags(1) = 101
flags(2) = 202
PRINT*,'BEFORE SUB: NTYPES_F =',NTYPES_F
CALL test_global()
END PROGRAM test
C CODE:
int
multi_c_ (int *memb_map)
{
int ret_value = -1;
return ret_value;
}
BEFORE SUB: NTYPES_F = 202
IN SUB: NTYPES_F = 202
it returns
BEFORE SUB: NTYPES_F = 202
IN SUB: NTYPES_F = 101
if I place the test_global routine before the multi_l subroutine (or take out the multi_l subroutine) it returns the correct result. Note that the program never calls the multi_l subroutine. The code works correctly using g95, gfortran, pgi, and sun compilers.
--------SOURCE--------
FORTRAN:
MODULE globmod
IMPLICIT NONE
INTEGER, DIMENSION(1:2) :: flags
INTEGER :: NTYPES_F
EQUIVALENCE(flags(2), NTYPES_F)
END MODULE globmod
MODULE F5
USE globmod
CONTAINS
SUBROUTINE multi_l()
USE iso_c_binding
IMPLICIT NONE
INTEGER(KIND=C_INT), DIMENSION(1:NTYPES_F) :: memb_map
INTEGER hdferr
INTERFACE
INTEGER FUNCTION multi_c(memb_map)
USE iso_c_binding
USE globmod
INTEGER(KIND=C_INT), DIMENSION(1:NTYPES_F) :: memb_map
END FUNCTION multi_c
END INTERFACE
memb_map = 9
hdferr = multi_c(memb_map)
END SUBROUTINE multi_l
SUBROUTINE test_global()
IMPLICIT NONE
PRINT*,'IN SUB: NTYPES_F =',NTYPES_F
END SUBROUTINE test_global
END MODULE F5
PROGRAM test
USE F5
IMPLICIT NONE
flags(1) = 101
flags(2) = 202
PRINT*,'BEFORE SUB: NTYPES_F =',NTYPES_F
CALL test_global()
END PROGRAM test
C CODE:
int
multi_c_ (int *memb_map)
{
int ret_value = -1;
return ret_value;
}
Link Copied
11 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is unclear what is happening here just yet. This is reproducible on Linux w/our latest 10.1 ifort/icc compilers. Our newer development compilers return the unexpected results regardless of the position of test_global().
Appreciate the nice reproducer. I will inquire about this with the Fortran Compiler Developers and post again when I have additional information.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks to Dr. Fortrans antidote heres a method that works.
Replace the USE usage in the interface specification with IMPORT as shown:
INTERFACE
INTEGER FUNCTION multi_c(memb_map)
IMPORT
INTEGER(KIND=C_INT), DIMENSION(1:NTYPES_F) :: memb_map
END FUNCTION multi_c
END INTERFACE
I will keep you updated on our handling the original form too.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Indeed that does work, except it will not compile using some of the other compilers mentioned (i.e. sun and pgi and older compilers that don't have IMPORT).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Work-around: Just add the following statement to globmod:
common /globmod_common/ flags
In my experience, it is common to discover compiler bugs (on all F9x compilers I have tried) when using constructs that should be valid but are not commonly used. Fortran9x programmers generally discourage the use of EQUIVALENCE statements because they have been often abused, even though there really are good reasons for them. Here, modules are not appropriately aware of the "old" equivalence statement, but common-blocks are.
I also once had problems using INTERFACE statements with argument descriptions that depend on variables in a common block, which is another example of mixing "old" and "new" syntax.
common /globmod_common/ flags
In my experience, it is common to discover compiler bugs (on all F9x compilers I have tried) when using constructs that should be valid but are not commonly used. Fortran9x programmers generally discourage the use of EQUIVALENCE statements because they have been often abused, even though there really are good reasons for them. Here, modules are not appropriately aware of the "old" equivalence statement, but common-blocks are.
I also once had problems using INTERFACE statements with argument descriptions that depend on variables in a common block, which is another example of mixing "old" and "new" syntax.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many compilers have had to support common and equivalence in ways which were often used up to 20 years ago. In some cases, this causes optimizations to be disabled silently.
On the other hand, gfortran is a stickler for not allowing extensions in the ways equivalence may be used.
On the other hand, gfortran is a stickler for not allowing extensions in the ways equivalence may be used.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
krahn@niehs.nih.gov:
Work-around: Just add the following statement to globmod:
common /globmod_common/ flags
Actually what started this all was us trying to remove the common statements. It seems a little counter intuitive to mix common statements and modules. Also the fact that we have to add old style !DEC$ to get the common statements to work on windows platforms with DEC/COMPAQ compilers.
!DEC$if defined(BUILD_HDF5_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: /globmod_common/
!DEC$endif
EQUIVALENCE has been around a long time but there is really no newer replacement for it unlike common statements and I think it is still in the newest standard. From a maintenance standpoint it would be messy to get rid of our EQUIVALENCE statements.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On Windows, to share a variable or COMMON from a DLL requires a directive - no matter whose compiler you use.
You are correct that EQUIVALENCE is still in the standard, though it is generally not considered good practice. Nevertheless, it's often what you need.
You are correct that EQUIVALENCE is still in the standard, though it is generally not considered good practice. Nevertheless, it's often what you need.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
breitenfeld:
Actually what started this all was us trying to remove the common statements. It seems a little counter intuitive to mix common statements and modules.
Agreed. However, the Standards developers discourage certain constructs to the point that most example Fortran95 code doesn't have them at all. The standards dislike the EQUIVALENCE so much that the F2003 standards doesn't even support C structs with unions. The result is that code not following the strict style of Fortran90 "purists" is prone to find compiler bugs. You sort of have to go "pure" Fortran90 style with modules, or stick to mostly Fortran77 and just use F90 features that you actually need.
By the way, are you an HDF developer? If so, I have an experimental HDF5 interface using F2003, which is much simpler than the F90 interface, and can even derive data structures from derived-type variables. I put off development for a while because F2003 support had some problems, which may be fixed in the current Intel compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I'm currently a HDF developer. We are investigating updating the Fortran wrappers to use some Fortran 2003 features which, as you mentioned, would allow us to handle derived data types directly by passing the C address via C_LOC. Actually, using Fortran 2003 we can also handle the HDF functions that have callbacks, such as iterating through a file, where the callback functions can be written in Fortran. This is a nice feature presently not available in the Fortran HDF interface.
Currently the new features work perfectly with the intel and g95 compilers, but are currently not working (mainly for lack of 2003 implementation) on the other 4 or so compilers we support..
Currently the new features work perfectly with the intel and g95 compilers, but are currently not working (mainly for lack of 2003 implementation) on the other 4 or so compilers we support..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
breitenfeld:
Yes, I'm currently a HDF developer. We are investigating updating the Fortran wrappers to use some Fortran 2003 features which, as you mentioned, would allow us to handle derived data types directly by passing the C address via C_LOC. Actually, using Fortran 2003 we can also handle the HDF functions that have callbacks, such as iterating through a file, where the callback functions can be written in Fortran. This is a nice feature presently not available in the Fortran HDF interface.
Currently the new features work perfectly with the intel and g95 compilers, but are currently not working (mainly for lack of 2003 implementation) on the other 4 or so compilers we support..
I have the C_LOC() working in HDF. Function pointers are new featuresd for Intel, so I have not tried them yet. I have a complete C interface along with Fortran-friendly wrapper functions for autmatic string handling. I also have working routines for finding derived-type offsets by using C_LOC() on members of a derived-type variable. An incomplete set of code online at: http://joekrahn.homelinux.com/hdf5_f2003/1.8/
I would send this to you directly, but the "send email reply" is not working in this forum interface. My e-mail is my last name
at niehs dot nih dot gov.
Joe Krahn
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For those awaiting a 10.1 resolution, the fix for this issue is now available at the Intel Registration Center (https://registrationcenter.intel.com) in the latest 10.1 update, package id: l_fc_p_10.1.022

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