- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need some guidance on modules and interfaces.
If this is an inappropriate forum, please forgive me and direct me to an appropriate information source.
I am trying to add some functionality to a set of API "user" functions by adding some optional arguments. That way the routines may be calledby earlier versions with no code changes. However, new additional functionality may be accessed by supplying "new" optional arguments. I am using (but new to) Intel Fortran Ver 9.0.
I have roughly the following setup:
MODULE DATA_A
IMPLICIT NONE
STRUCTURE (derived data type) definition
for type: DATA_A_TYPE
END MODULE DATA_A
MODULE DATA_B
IMPLICIT NONE
more structure (derived data type) definitions
for type: DATA_B_TYPE
END MODULE DATA_B
MODULE INTERNAL_STUFF
USE DATA_A
USE DATA_B
CONTAINS
..
many "internal" functions
..
END MODULE INTERNAL_STUFF
MODULE USER_STUFF
USE DATA_A
USE DATA_B
USE INTERNAL_STUFF
CONTAINS
user functions, some with optional arguments such as:
.
REAL FUNCTION USER1( ARGA, ARGB, OPTNL_ARG )
IMPLICIT NONE
TYPE (DATA_A_TYPE)ARGA
TYPE (DATA_B_TYPE)ARGB
REAL, OPTIONAL :: OPTNL_ARG
.
calls to "internal" functions in MODULE: INTERNAL_STUFF
.
END FUNCTION USER1
other "user" functions
END MODULE USER_STUFF
PROGRAM MAIN_PROGRAM
IMPLICIT NONE
USE DATA_A
USE DATA_B
USE USER_STUFF
TYPE(DATA_A_TYPE)ARGA
TYPE(DATA_B_TYPE)ARGB
.
.
X1 = USER1( ARGA, ARGB, ARG3 ) ! Works O-K
X2 = USER1( ARGA, ARGB ) ! Blows up with run-time error
!"forrtl: severe (157): Program Exception - access violation"
.
END PROGRAM
IMPLICIT NONE
STRUCTURE (derived data type) definition
for type: DATA_A_TYPE
END MODULE DATA_A
MODULE DATA_B
IMPLICIT NONE
more structure (derived data type) definitions
for type: DATA_B_TYPE
END MODULE DATA_B
MODULE INTERNAL_STUFF
USE DATA_A
USE DATA_B
CONTAINS
..
many "internal" functions
..
END MODULE INTERNAL_STUFF
MODULE USER_STUFF
USE DATA_A
USE DATA_B
USE INTERNAL_STUFF
CONTAINS
user functions, some with optional arguments such as:
.
REAL FUNCTION USER1( ARGA, ARGB, OPTNL_ARG )
IMPLICIT NONE
TYPE (DATA_A_TYPE)ARGA
TYPE (DATA_B_TYPE)ARGB
REAL, OPTIONAL :: OPTNL_ARG
.
calls to "internal" functions in MODULE: INTERNAL_STUFF
.
END FUNCTION USER1
other "user" functions
END MODULE USER_STUFF
PROGRAM MAIN_PROGRAM
IMPLICIT NONE
USE DATA_A
USE DATA_B
USE USER_STUFF
TYPE(DATA_A_TYPE)ARGA
TYPE(DATA_B_TYPE)ARGB
.
.
X1 = USER1( ARGA, ARGB, ARG3 ) ! Works O-K
X2 = USER1( ARGA, ARGB ) ! Blows up with run-time error
!"forrtl: severe (157): Program Exception - access violation"
.
END PROGRAM
I presume I need an interface block. But I don't know where to put it. I tried it in module: USER_STUFF both before and after the CONTAINS, and it complains about duplicate routine names. I also tried making it a separate module as:
MODULE USER_INTERFACE
INTERFACE
USE DATA_A
USE DATA_B
FUNCTION USER1( ARGA, ARGB, OPTNL_ARG )
REAL USER1
TYPE(DATA_A_TYPE)ARGA
TYPE(DATA_B_TYPE)ARGB
REAL, OPTIONAL :: OPTNL_ARG
END INTERFACE
END MODULE USER_INTERFACE
INTERFACE
USE DATA_A
USE DATA_B
FUNCTION USER1( ARGA, ARGB, OPTNL_ARG )
REAL USER1
TYPE(DATA_A_TYPE)ARGA
TYPE(DATA_B_TYPE)ARGB
REAL, OPTIONAL :: OPTNL_ARG
END INTERFACE
END MODULE USER_INTERFACE
And tried USEing USER_INTERFACE in MODULE: MAIN PROGRAM
with the same problem.
with the same problem.
Sorry, I am an old Fortran 77 man and not very familiar with new Fortran 90 features such as modules and interfaces.
ThankS,
Richard Ahlvin
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you put the routine in a module, and use that module, you already provided an "explicit interface" -- that's actually the simplest (and best) way to do it. Since the program builds correctly, there seems to be no interface problem.
However, you did not show us how you exactly handle the OPTNL_ARG within USER1. The bottom line is, in the called routine you have to guard the situation when it's not present in the actual arg-list. If it's missing, it is passed as a NULL reference, and any attempt to read/write it (except PRESENT function) will result in an access violation. Thus, there's only two things you may do with a non-present optional argument:
1) Test its presence with PRESENT function
2) Pass it to another routine which expects an optional argument in that place. (You don't have to test if it's PRESENT in that case)
The common technique to handle the situation is to declare an auxiliary variable and assign a value to it, like this:
Jugoslav
However, you did not show us how you exactly handle the OPTNL_ARG within USER1. The bottom line is, in the called routine you have to guard the situation when it's not present in the actual arg-list. If it's missing, it is passed as a NULL reference, and any attempt to read/write it (except PRESENT function) will result in an access violation. Thus, there's only two things you may do with a non-present optional argument:
1) Test its presence with PRESENT function
2) Pass it to another routine which expects an optional argument in that place. (You don't have to test if it's PRESENT in that case)
The common technique to handle the situation is to declare an auxiliary variable and assign a value to it, like this:
REAL, OPTIONAL, INTENT(IN):: Tolerance
REAL:: defTolerance
defTolerance = 1.e-6
IF (PRESENT(Tolerance)) defTolerance = Tolerance
!Use only defTolerance below
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks...
That was the problem.
I had overlooked that specific problem logic caused some code to be executed that was using the optional argument item directly rather than the copy as I had intended.
That was the problem.
I had overlooked that specific problem logic caused some code to be executed that was using the optional argument item directly rather than the copy as I had intended.

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