Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Practilce help with OPTIONAL

holmz
New Contributor I
1,243 Views
I have a subroutine that call another subroutine. The calling subroutine has this in it: ... REAL(KIND=8), DIMENSION(7) :: CP = RESHAPE((/1.0D0/), SHAPE (/7/), PAD(/0.0D0/) ) REAL(KIND=8), DIMENSION(7) :: SP = RESHAPE((/1.0D0/), SHAPE (/7/), PAD(/0.0D0/) ) INTEGER(KIND=4), PARAMETER :: SIX = 6 LOGICAL(KIND=4) :: R_DeBug = .FALSE. LOGICAL(KIND=4) :: S_DeBug = .FALSE. INTERFACE SUBROUTINE SICOJT(Call1, Call2, Call3, Call3, Call4, Call5) INTEGER(KIND=4) :: Call1 REAL(KIND=8), DIMENSION(7) :: Call2 REAL(KIND=8), DIMENSION(7) :: Call3 REAL(KIND=8), DIMENSION(7) :: Call4 LOGICAL(KIND=4), OPTIONAL :: Call5 END SUBROUTINE SICOJT END INTERFACE IF(R_DeBug) THEN D WRITE(*,*) 'RoutineX:1600' CALL SICOJT(Siz, CP(2), SP(2), P2, R_DeBug) ELSE D WRITE(*,*) 'RoutineX:1600' CALL SICOJT(Siz, CP(2), SP(2), P2, S_DeBug) ENDIF .... The compiler error says ifort: warning #101082: disabling optimisation; runtime debug checks enabled ./mycode.for (1839): error #8000: There is a conflict between local interface block and external interface block. The later subrouttine is as follows: SUBROUTINE SICOJT(L, C, S, T, DBG) IMPLICIT NONE !RH  IMPLICIT REAL*8 (A-H, O-Z) !Args INTEGER(KIND=4) , INTENT(IN ) :: L REAL(KIND=8), DIMENSION(L), INTENT(INOUT) :: S REAL(KIND=8), DIMENSION(L), INTENT(INOUT) :: C REAL(KIND=8) ,INTENT(IN ) :: T LOGICAL(KIND=4) , INTENT(IN ) :: DBG compiler is composer_xe_2013 sp1. 1. 106 intel 64. Just warning on composer_xe_2011 sp 1 .11.339 intel 64. I would like to know what I am doing wrong. :) Thanks, RH aka ~Holmz
0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
1,243 Views

Your INTERFACE block and your SUBROUTINE declarations are different

The INTERFACE is not passing the length (L) argument the array dimensions are fixed at 7, whereas the SUBROUTINE is expecting the dimension (L) to be passed.

The INTERFACE declares the last argument as optional whereas the SUBROUTINE does not.

Also the interface is not specifying INTENT(...) the subroutine is.

Jim Dempsey

View solution in original post

0 Kudos
7 Replies
jimdempseyatthecove
Honored Contributor III
1,244 Views

Your INTERFACE block and your SUBROUTINE declarations are different

The INTERFACE is not passing the length (L) argument the array dimensions are fixed at 7, whereas the SUBROUTINE is expecting the dimension (L) to be passed.

The INTERFACE declares the last argument as optional whereas the SUBROUTINE does not.

Also the interface is not specifying INTENT(...) the subroutine is.

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor III
1,243 Views

Holmz,

Can you make SICOJT a module procedure and "use" the module in your caller so you don't have to specify an explicit interface?  If not, you have to take the extra responsibility to ensure your interface is fully consistent with the actual procedure implementation which is not the case at present as explained by Jim.

0 Kudos
holmz
New Contributor I
1,243 Views

Yeah  Jim - I tried it with dimension(7) and dimension (*)., and with the intent in the interface. 
About all the combinations that I could think of for about an hour or more.
The subroutine does have OPTIONAL specified for DBG, as does the calling interface. Unfortunately I had to print this out and poke in the section by hand at home... Which never proves to be helpful for me cause.

The "----------^" was aimed at the first argument "call1", but I suspect that was not really a clue and I spent a lot of time changing that around in different ways..


FortranFan> While I could do that, this is part of a bunch of existing code. But wth a hugh number of warning, with some subroutines and calls that differ by 3 extra arguments, and some real*8 going to real*4. All I really want to do is to generally clean it up to compile without warnings, or with a lot less and have it run roght.

The optional arguement for debug was so that I do not have to change every peice of code that calls the subroutine I was wanting to debug. But it seems to be quicker tp do that than to use the "optional". The optional has always seemed to be hit or miss for me.

0 Kudos
holmz
New Contributor I
1,243 Views
Hanging head in shame. I am still not entirely sure what I changed, but it is working after a fresh cut-n-paste from the subroutine to the interface spec., I think that the DIMENSION(*) was changed to a DIMENSION(6)... so maybe that was it?? So thanks, the comments made re-look at the whole thing again. ...and second frustratiion soon followed. INTERFACE SUBROUTINE X(HCB, DBG) INCLUDE 'headers.inc' RECORD /header/ HCB LOGICA(KIND=4), OPTIONAL, INTENT(IN) :: DBG END SUBROUTINE X END INTERFACE The -----^ is pointing up at HCB. I am using 5 other _interface.inc files in numerous code and they are all working like a champ, just not the one with the RECORD. I cut-n-pasted this directly from the SUBROUTINE to the INTERFACE, and I prefer to use "USE" as well as "TYPE", but I do not want to do more a wholesale change of the code if I can help it. Passing records in the SUBROUTINE calls usually make me generally uneasy, but I have no issues with TYPE/KIND passing. It sounds a bit odd when I actually write it down???...
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,243 Views

Try to move away from using INCLUDE 'some header.inc'

This will introduce issues where/when source files are compiled with different but same named include files. Transition to using modules, as this will assure consistent interfaces (as well as errors when calls do not match). The INCLUDE presents no such guarantee.

Jim Dempsey

0 Kudos
holmz
New Contributor I
1,243 Views

jimdempseyatthecove wrote:

Try to move away from using INCLUDE 'some header.inc'

This will introduce issues where/when source files are compiled with different but same named include files. Transition to using modules, as this will assure consistent interfaces (as well as errors when calls do not match). The INCLUDE presents no such guarantee.

Jim Dempsey



^Exactly^ Jim...

For code that wears my name, I am using modules and USE. So I concur with your recommendation.


But that begs the question of what one should do with existing code that needs modification??
In my enthusiasm, or my thoroughness, I turned "-check all" on (really I generally mostly care -check bounds).

After a few uninitialized variables were sorted out, I then tackled the bounds violations.
Then I turned -warn on... (oh Joy... I thought I was about done 2-1/2 weeks ago, before -warn all).

So I then found real*4 and real*8 getting passed around and some subroutine and calls with 'ms. matched' numbers of arguments, and the usual unused variables being so prodigious that the compiler eventually aborts with "too many warnings". Mostly the same include is in all the subroutines and functions, and that one CANNOT be changed, but it could be inclued in a module. After a few hundred in the actual code are excised, I generally disable the "-check unused".

So I delve in with IMPLICIT NONE, and INTENT(in/out), and added INTERFACE SPECIFICATIONS for the optional arguments. And a bevy of "D" lines to sort out where the index are striding beyond the fence.

 

So that begs the question of how deep and how far one should work on existing code?
Usually if it runs the same with "O0 -check bounds -d-lines" or "-check all" and the same with -O2 or -O3, then that is my minimum level of acceptability. Then later (after some burn in period) I'll recompile with "02 -no-dlines" for the speed.
I usually do not have issues with "-warn all", so I am at a loss to how to tackle some of the interface issues.

The INTERFACE STATEMENTS are working fine for me except for arguments which are RECORDS (and they may have  MAP/UNION in those records as well)

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,243 Views

Replacing INCLUDE 'file.inc' with USE MOD_file is generally straightforward. It may require that you relocate the line. I use FPP and conditional compile statements

subroutine foo()
#ifdef USE_MODULES
  USE MOD_file
#endif
  implicit none
  real :: LocalVars
#ifndef USE_MODULES
  INCLUDE 'file.inc'
#endif
  ...

This way I can easily switch back and forth while shaking out any bugs.

What I find that is the lid of the can of worms is when different source files use the same /named/ common but with different variable declarations.

>>The INTERFACE STATEMENTS are working fine for me except for arguments which are RECORDS (and they may have  MAP/UNION in those records as well)

For those, I tend to use a user defined type that holds the RECORD and/or MAP/UNION.

Jim Dempsey

0 Kudos
Reply