Wrong associated status and values when chaining class pointers

Wrong associated status and values when chaining class pointers

We faced some difficulties when constructing linked list using class pointers.

The attached example illustrates the various problems we are facing. These problems occur with both IVF v11.1.065 and IVF 2011.0.055. I did not have a chance to test the latest v11.1 release. All problems only occur if the pointer in the list item is a class pointer instead of type.

Test 1: The problem here occurs only in debug mode. We allocate a first list item and then ask for the association status of the next pointer in the first list item through differenet access paths. They should all return false, as the second item has not been allocated. However, in debug mode we get true for two of the three access modes.

Test 2: Now we have allocated the second list item and thereforeexpect the association status to be true in all cases, however, with the access through a type pointer, we get false.

Test 3: Accessing data values from the base class through a type pointerreturns a bogus value. I think, typically you shouldn't use a type pointer for access here and I am not 100% sure that this is actually legal. However, it should either work correctly or give an error if not legal.

Best regards,
Thomas
Code:

PROGRAM LinkedList
IMPLICIT NONE
TYPE :: tBaseListItem
  REAL :: Val
  CLASS(tBaseListItem), POINTER :: Next
END TYPE

TYPE :: tListHeader
  CLASS(tBaseListItem), POINTER :: First
END TYPE

TYPE(tListHeader) :: ListHeader
TYPE(tBaseListItem), POINTER :: TypePtr
CLASS(tBaseListItem), POINTER :: ClassPtr

ALLOCATE( tBaseListItem :: ListHeader%First)
ListHeader%First%Val = 1
TypePtr => ListHeader%First
ClassPtr => ListHeader%First
! Wrong associated status for non-associated, chained pointers in debug mode
WRITE(*,*) 'Test 1'
WRITE(*,*) 'Expected result: F F F'
WRITE(*,*) 'Actual result:  ', ASSOCIATED(ListHeader%First%Next), ASSOCIATED(TypePtr%Next), ASSOCIATED(ClassPtr%Next)

! Now allocate a second list item
ALLOCATE( tBaseListItem :: ListHeader%First%Next )
! Wrong associated status for associated pointer referenced through type pointer (release and debug)
WRITE(*,*) 'Test 2'
WRITE(*,*) 'Expected result: T T T'
WRITE(*,*) 'Actual result:  ', ASSOCIATED(ListHeader%First%Next), ASSOCIATED(TypePtr%Next), ASSOCIATED(ClassPtr%Next)
! Now assign a value to val in the second list item and access it using different means
ListHeader%First%Next%Val = 2.0
TypePtr => ListHeader%First%Next
ClassPtr => ListHeader%First%Next
! The access through the type-pointer gives a bogus value
WRITE(*,*) 'Test 3'
WRITE(*,*) 'Expected result: 2.0 2.0 2.0'
WRITE(*,*) 'Actual result:  ', ListHeader%First%Next%Val, TypePtr%Val, ClassPtr%Val
END PROGRAM LinkedList

For completeness, the result I get:
Debug version:
Test 1
Expected result: F F F
Actual result: T F T
Test 2
Expected result: T T T
Actual result: T F T
Test 3
Expected result: 2.0 2.0 2.0
Actual result: 2.000000 4.9768180E-39 2.000000

Release version:
Test 1
Expected result: F F F
Actual result: F F F
Test 2
Expected result: T T T
Actual result: T F T
Test 3
Expected result: 2.0 2.0 2.0
Actual result: 2.000000 5.0046982E-39 2.000000

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Should you not define the pointer ListHeader%First%Next on line-23 before applying the ASSOCIATED intrinsic function to it?

Adding the initialization => NULL() on line-5 would remove this objection.

I have suspicions about the validity of the pointer-assignment of a class pointer to a type pointer on lines-18 and 33. I think that this may be in violation of the type compatibility rules.

For these lines, Gfortran 4.5 says

$> gfortran -std=f2003 boehme.f90 
boehme.f90:18:

TypePtr => ListHeader%First
1
Error: Different types in pointer assignment at (1); attempted assignment of CLASS(tbaselistitem) to TYPE(tbaselistitem)
boehme.f90:33:

TypePtr => ListHeader%First%Next
1
Error: Different types in pointer assignment at (1); attempted assignment of CLASS(tbaselistitem) to TYPE(tbaselistitem)

Hi mecej4,

thanks for your reply. Good catch. I did check the Chapman book again, and it really seems that the association status is undefined after declaration.So I guess that the behavior is actually fine. However, it is still weird that it is inconsistent depending on the method you access that same pointer.

As for the assignment of the TYPE pointer to the CLASS pointer, I also believe that thisis not beallowed. However, if it is not allowed, it should generate a compile time error.

regards,
Thomas

My reading suggests that gfortran is incorrect here. The CLASS pointer has a dynamic type and the dynamic type of ListHeader%First at the time of the assignment is tBaseListItem, the same as that of TypePtr.

Retired 12/31/2016

I can't really say if it's correct or not, but I think this issue should be addressed in a future version. It did take a while in our code to find out why it was not working correctly and I imagine others could do the same "mistake" as well.If the TYPE pointer instead of a class pointer is not valid, the compiler should give an error message.If it is valid, then the compiler is doing something wrong, as I am getting the wrong value using the type pointer. Note that the value you get is actually the value of the previous element, i.e. is seems that Next pointer is just omitted.regards,Thomas

Sorry for taking so long to get back to this. I have determined that TypePtr is in fact not pointing to the correct location. I have escalated this as issue DPD200164422. Either the assignment should be done correctly or an error should be given. I'll let you know what we find.

Retired 12/31/2016

This error was fixed in 12.0 Update 3.

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today