Silverfrost Forums

Welcome to our forums

Character value gets lost

5 Jan 2023 10:28 #29759

The following program may be eligible for an award for the most weird and useless nonsense, but it generates an incorrect result when compiled with /FULL_DEBUG. The program is on the long side, but I have tried hard to simplify it, and it seems that with almost any change, the problem disappears.

The program (in the first code segment) calls a subroutine s1, which is supposed to copy the value of getsLost into ctest, but ctest prints as blank. The module is broken into two halves because it is apparently too long. Subroutine s1 performs a set of apparently meaningless operations, calling functions and subroutines most of which do essentially nothing, but somehow they combine to lose the value of getsLost. All the code between lines 32 (starting immediately after the 'Do nothing meaningful' comment) and 76 (immediately before the 'Try to use the value of getsLost' comment) has no intentional logic - it is purely what is left after a very long process of reducing a much larger programme to a minimum. There are many obvious ways to simplify this section of the code, but not, I have found, without making the error disappear.

I have the same problem occurring without using /FULL_DEBUG, but it will be a large task to try to isolate that. I am hoping the problem can be identified using this example.

Program p
   Use m
   Integer                         :: i1
   Logical                         :: l1
   Character(Len= 2)               :: getsLost = '?'
   Character(Len=64), Dimension(2) :: cs1, cs2
!
   i1 = 3
   t3%i1 = 1
   t3%i2 = 2
   t3%i3 = 3
   Call s1 (getsLost, cs1, cs2, l1, i1)
   Print*, ctest
End Program p
5 Jan 2023 10:36 #29760

Module part 1:

Module m
!
   Type t
      Integer :: i1
      Integer :: i2
      Integer :: i3
   End Type t
   Interface Operator(<)
      Module Procedure f1
   End Interface
!
   Integer          :: i3 = 1
   Integer          :: i4 = 1
   Character(Len=2) :: c1, ctest
   Logical          :: l2
   Type(t)          :: t1, t2, t3
!
Contains
!
 Subroutine s1 (getsLost, cs1, cs2, l1, i1, &
            i2, is1, is2, at)
   Integer                                  :: i1
   Character(Len=*)                         :: getsLost
   Character(Len=*), Dimension(:)           :: cs1, cs2
   Logical                                  :: l1
!
   Integer,                        Optional :: i2
   Type(t),                        Optional :: at
   Integer,          Dimension(:), Optional :: is1, is2
!
! Do nothing meaningful
   If (Present(i2)) Then
      l2 = (i2 > 0)
   Else
      l2 = .false.
   End If
   l1 = Present(i2)
   i3 = Count([l1, l2])
   c1 = f2(i3,  1, i4)
   c1 = f2(i3,  1, i4) ! - needs to be repeated -
   l2 = (c1 == ' ')
   t1%i1 = 1
   t1%i2 = 1
   t1%i3 = 1
   t2%i1 = i1
   t2%i2 = i1
   t2%i3 = 1
   Call s2 (i3*i4, t2)
   If (i3 < i1) Then
      i3 = i4
      If (Present(i2)) i2 = 2
   End If
   i3 = t2%i1
   If (Present(at)) Then
      If (at%i2 < 1) Then
         at%i1 = t3%i1
         at%i2 = t3%i2 + at%i2
         at%i3 = 1
         Do
            If (at%i2 < 0) Exit
            at%i2 = at%i2 + 1
            at%i1 = at%i1 - 1
         End Do
      End If
      If (t2 < t1) i4 = 2
   End If
   Select Case (i4)
    Case (1)
      If (l1) Then
         i4 = i1
      Else
         i4 = i1
      End If
    Case Default
      i4 = i1
   End Select
! Try to use the value of getsLost
   ctest = f0(getsLost, i4, l2, .false.)
   Return
!
 Contains
!
  Character(Len=256) Function f0(getsLost, i, l1, l2)
   Integer          :: i
   Character(Len=*) :: getsLost
   Logical          :: l1, l2
   f0 = Trim(getsLost)
  End Function f0
 End Subroutine s1
!

Module part 2:

 Subroutine s2 (i, d)
   Integer  :: i
   Type(t) :: d
   Return
 End Subroutine s2
!
 Logical Function f1(t1, t2)
   Type(t), Intent(In) :: t1, t2
   f1 = .false.
 End Function f1
!
 Character Function f2(i1, i2, i3)
   Integer :: i1, i2, i3
   f2 = ' '
 End Function f2
End Module m
1 Mar 2023 4:39 #29972

I appreciate that this example was not ideal, but I'm wondering whether Silverfrost had any thoughts about it. I am trying to construct a URL that is used to download some data, but because of the bug, part of the URL gets lost. And without having a clearer sense of what is wrong in the example, I do not know how to code a work-around. The code works perfectly ok with other compilers.

2 Mar 2023 7:36 #29974

Simon

I am sorry but I missed your initial post on Jan 5th.

I will take a look at your code as soon as possible.

2 Mar 2023 1:45 #29976

Simon

As far as I can see, your code works correctly except for Win32 when using /FULL_DEBUG and no other debugging options such as /CHECK.

It can be fixed in this particular context by initialising 'getslost' in a runtime assignment instead of in its declaration.

/FULL_DEBUG is like /DEBUG but it allows you to view PARAMETERs when debugging. It serves no purpose in this context because there are no PARAMETERs in the code.

2 Mar 2023 5:13 #29977

Thanks Paul. I made a few changes, which seem to have fixed the problem in 8.96. I will aim to provide a better example if the problem reappears without /FULL_DEBUG

Please login to reply.