Silverfrost Forums

Welcome to our forums

Undefined variable error/bug with user defined type

9 Aug 2007 8:22 #2161

I’m getting the following run-time error in one of my Win32 programs and I cannot see why.

*** Error 112, Reference to undefined variable, array element or function result (/UNDEF)

I’ve constructed a small program that demonstrates the error and consists of a Main and two Modules as follows.

C ------------------------------------------------------------
C DEMO.FOR
      PROGRAM DEMO

      USE Calc

      CALL WX_AddErrors ()                      !<<<<<< Line 13

      PRINT *, 'Demo program has run'

      END

! -----------------------------------------------------------
MODULE Calc

  USE Dict, ONLY: Dictionary_t,  &
                  Dict_Len,      &
                  Dict_reset

  PRIVATE

  TYPE(Dictionary_t), PRIVATE :: xDic

  PUBLIC :: WX_AddErrors

CONTAINS

! ----------------------------------------------------------
  SUBROUTINE WX_AddErrors ()
    INTEGER(KIND=SELECTED_INT_KIND(9)) :: dLen

!    xDic%nItems = 0          !This (uncommented) fixes problem ?!!!

    dLen = Dict_Len(xDic)                 !<<<<<< Line 30
    IF (dLen == 0) RETURN

    !Processing code goes here (omitted for clarity)

    CALL Dict_Reset (xDic)

  END SUBROUTINE


END MODULE

! --------------------------------------------------------------
MODULE Dict

  PRIVATE

  INTEGER(KIND=SELECTED_INT_KIND(9)), PARAMETER, PRIVATE :: MAX_ITEMS     = 50
  INTEGER(KIND=SELECTED_INT_KIND(9)), PARAMETER, PUBLIC  :: DICT_ITEM_LEN = 100

  TYPE, PUBLIC :: Dictionary_t
    PRIVATE
    INTEGER(KIND=SELECTED_INT_KIND(9))                    :: nItems = 0
    CHARACTER(LEN=DICT_ITEM_LEN), DIMENSION(1: MAX_ITEMS) :: key    = ''
    CHARACTER(LEN=DICT_ITEM_LEN), DIMENSION(1: MAX_ITEMS) :: value  = ''
  END TYPE

  PUBLIC :: Dict_Reset,  &
            Dict_Len

CONTAINS

! -----------------------------------------------------
! Resets the dictionary to empty
!
  SUBROUTINE Dict_Reset (dict)
    TYPE(Dictionary_t), INTENT(INOUT) :: dict

    dict%nItems = 0

  END SUBROUTINE

!------------------------------------------------------
! Returns number of entries in the dictionary
!
  FUNCTION Dict_Len (dict)
    INTEGER(KIND=SELECTED_INT_KIND(9)) :: Dict_Len

    TYPE(Dictionary_t), INTENT(IN) :: dict

    Dict_Len = dict%nItems                !<<<<<< Line 45

  END FUNCTION

END MODULE

I’m using a recently downloaded FTN95 Personal Edition, which is declared as version 5.10 on the Polyhedron web site but prints version 4.9.0 on the console. I compile with the options, /ISO /IMPLICIT_NONE /NO_SCALAR_TO_ARRAY /RESTRICT_SYNTAX /CHECKMATE /BRIEF /ERRORLOG and then link with SLINK. The run-time error information is as follows (I’ve flagged the offending line numbers in the above code).

DICT!DICT_LEN - in file dict.f90 at line 45 [+0041] CALC!WX_ADDERRORS - in file calc.f90 at line 30 [+002c] main - in file demo.for at line 13 [+0031]

The problem seems to be that the variable, xDic in module Calc, or one of its members, is being seen as uninitialised or undefined. I cannot see how this can be since all the members are initialised at the point of defining the Dictionary_t type in module Dict.

Even stranger is the fact that when I uncomment the statement, “xDic%nItems = 0” in subroutine WX_AddErrors in module Calc, the problem goes away, which seems to confirm that the issue is with initialisation. However, I cannot see how this statement should compile. Surely the compiler should issue an error message here because all the members of xDic are private (see definition of Dictionary_t in module Dict).

I would really appreciate anyone telling me where I’m going wrong.

Keith

11 Aug 2007 3:21 #2164

Assuming this is valid Fortran (and I think it is valid) then your code reveals a missing feature in FTN95. Clearly the initialisation as not be implemented by the compiler.

For the moment it will be necessary to do the initialisation as an assignment statement.

11 Aug 2007 4:35 #2166

Thanks for replying and I agree. It is not too much of a hassle for me to provide an initialisation routine that must be called before using module Dict or Calc.

I think what really surprised me was FTN95 allowing an assignment (xDic%nItems = 0) to a private member of the Dictionary_t type outside of module Dict. I tried this with an ancient Digital Fortran compiler and got,

Error: The parent type of this field is use associated with the PRIVATE fields attribute [NITEMS]

FTN95 should give some equivalent message.

12 Aug 2007 11:26 #2167

Is there any requirement to define modules in order, so that they are defined before being used ? The reverse order in the example code doesn't look right

13 Aug 2007 6:05 #2168

They are in separately compiled files and the .obj are then linked.

PROGRAM DEMO in demo.for, MODULE Calc in Calc.f90, and MODULE Dict in Dict.f90.

Like I say, the program compiles and runs with no error if I include the assignment, xDic%nItems = 0. The problem has nothing to do with order of modules. It is a bug in FTN95.

13 Aug 2007 12:58 #2169

The initialisation works OK for small arrays (key and value) so this is a bug rather than a missing feature.

The PRIVATE attribute works OK for a main program or external subroutine. Again this is a bug.

We hope to fix both bugs in time for the next release.

Please login to reply.