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

Pointers and compiler error

gertdeboom
Beginner
610 Views
I'm experimenting a little with some form of cross-development between Compaq Visual Fortran 5.0D (used in a Windows 2000 environment) and Compaq Fortran V7.4A-1588-46B4K (used in OpenVMS 7.3 on Alpha).

The following code is running in both environments:

MODULE MOD_FORM
INCLUDE 'COMPABILITY.INC'
TYPE, PUBLIC:: FORM
CHARACTER*12 NAME
!DEC$ IF DEFINED (WINDOWS)
INTEGER*4 ONINPUT_PTR
!DEC$ ELSE
INTEGER*8 ONINPUT_PTR
!DEC$ ENDIF
END TYPE

PUBLIC:: FRM_SET_ONINPUT,FRM_INIT,FRM_EDIT

CONTAINS

!** FRM_SET_ONINPUT
SUBROUTINE FRM_SET_ONINPUT(OBJECT, FUNC)
TYPE(FORM) OBJECT
IF (.FALSE.) CALL FUNC('')
OBJECT%ONINPUT_PTR = %LOC(FUNC)
END SUBROUTINE

!** FRM_INIT
SUBROUTINE FRM_INIT(OBJECT)
TYPE(FORM) OBJECT
OBJECT%NAME = 'FIELDNAME'
END SUBROUTINE

!** FRM_EDIT
SUBROUTINE FRM_EDIT(OBJECT)
TYPE(FORM) OBJECT
EXTERNAL DUMMY
!DEC$ IF DEFINED (WINDOWS)
INTEGER*4 EVALUATION
!DEC$ ELSE
INTEGER*8 EVALUATION
!DEC$ ENDIF

POINTER(EVALUATION, DUMMY)
EVALUATION = OBJECT%ONINPUT_PTR
CALL DUMMY(OBJECT)
END SUBROUTINE
!DEC$ IF DEFINED (WINDOWS)
!DEC$ UNDEFINE WINDOWS
!DEC$ ENDIF
END

!** DUMMY
SUBROUTINE DUMMY
END

!** PROGRAM TEST
PROGRAM TEST
USE MOD_FORM
EXTERNAL BEFOREINPUT
TYPE(FORM) TSTFRM

CALL FRM_SET_ONINPUT(TSTFRM, BEFOREINPUT)
CALL FRM_INIT(TSTFRM)
CALL FRM_EDIT(TSTFRM)
END

!** BEFOREINPUT
SUBROUTINE BEFOREINPUT(TSTFRM)
USE MOD_FORM
TYPE(FORM) TSTFRM

WRITE(6,*) TSTFRM%NAME
END

The file "COMPATABILITY.INC" is supposed to contain
the line:

!DEC$ DEFINE WINDOWS

in the windows version. That way I'm making sure I
have one code base.

It is compiling and working correctly.

Only one thing worries me (and I'm not able to explain;
but I'm someone who doesn't like to learn theory) and
that is this line:

IF (.FALSE.) CALL FUNC('')

It doesn't do anything (apart from faking the compiler
I suppose) but if I skip it from the code both
compilers give the following error:

"This actual argument must not be the name of a procedure."

Could someone reading this forum explain me what is
happening here ? And is it safe to use this construction
in an actual program ?

I already know about the limited range of compilers
supporting this kind of pointer usage, but porting is
not an issue here.

Thanks in advance,
Gert
0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
610 Views
Implicit typing is your enemy here.

Without that line, compiler does not know what's the type of FUNC argument, so it concludes that it's implicitly a REAL. When it sees call to FRM_SET_ONINPUT where the actual argument is a procedure, it complains about the mismatch.

What you really want is
EXTERNAL Func
declaration in FRM_SET_ONINPUT.

Few more notes: you better use standard F90 kinds instead of INTEGER*x form. Further, symbol _WIN32 is always defined in DVF for 32-bit Windows. It's far better to use:
!==8<==File "compatibility.inc"===
!DEC$IF DEFINED(_WIN32)
INTEGER, PARAMETER:: PTR = 4
CHARACTER(1), PARAMETER:: PATH=""
!DEC$ELSE
INTEGER, PARAMETER:: PTR = 8
CHARACTER(1), PARAMETER:: PATH="/"
!DEC$ENDIF
!
!==8<==File "Mod_form.f90"===
INCLUDE "compatibility.inc"
INTEGER(PTR):: ONINPUT_PTR
...
If you're lucky, you'll use !DEC$ only on one place -- in compatibility.inc. Note that I included PATH parameter as well; maybe you'll need it, like:
OPEN(11,FILE="."//PATH//ADir//PATH//File.txt).

As I've stressed already, I recommend using IMPLICIT NONE throughout -- requires more discipline but protects you from making stupid errors.

Regards
Jugoslav
0 Kudos
gertdeboom
Beginner
610 Views
> What you really want is EXTERNAL Func

Kind of stupid. I knew I was faking the compiler somehow. Should have thought about it.

> Few more notes: you better use standard F90 kinds
> Further, symbol _WIN32 is always defined in DVF
> I recommend using IMPLICIT NONE

Thanks for your (really fast) answer and also for the other tips,
Gert
0 Kudos
Reply