Reference Equality operator. Your opinion

I just found that, it seems, one of the oldest and frequently used logical operator in CW is not documented. Therefore, it’s impossible to argue whether it works correctly or not in some context. In my opinion, the compiler generates the wrong code if the reference us not just an address:

S     STRING(20)
Ref1  &STRING
Ref2  &STRING
...
  Ref1 &= S[1 : 3]
  Ref2 &= S[1 : 10]

In this context the reference equality operator

  IF Ref1 &= Ref2
  ...
  END

evaluated as TRUE. Yes, both Ref1 and Ref2 refer to the same memory but the size of referenced memory is different. As result, dereferenced values of Ref1 and Ref2 are not equal and effect of assignments

  Ref1 = '0123456789'
  Ref2 = '0123456789'

is very different.

The problem exists for reference variables of types the ADDRESS function is applicable for. So, it’s possible to compare addresses only for such reference variables. The reference equality operator could do more work.

Your opinion, how the reference equality operator has to work for references including not addresses only?

I think your ref1 example value are incorrect, but I know what you mean.

To me, I was always only comparing the reference address, and this issue never came up.

It could possibly break existing code if you were to change the way comparison works.

I wonder if another operator kind of like deep assign would be useful, or maybe just a StringRefComparison() function would be fine. Perhaps the function could have switches for address, size, and value equality as a parameter.

I agree with you that it is wrong but I am not sure whether it should be fixed. If it were fixed it could silently break someone’s code that has been happily working for years.

Of course if that were the case (relying on buggy behaviour) then you could argue it is about time they fixed their own code to use if address(ref1) = address(ref2).

Fortunately I don’t think this &= would be used very much by average Clarion users in their own code.

Good idea. That would cover all bases.

If addresses and sizes are equal, no necessity to compare values. In any case, it’s more easy to compare SIZEs:

  IF SIZE(Ref1) = SIZE(Ref2)
  ...
  END

in addition to compare addresses.

Before you posted this I was wondering if SIZE would work and did this quick test to be sure.

  PROGRAM
  MAP .
grp1                GROUP
str1                  STRING(20)
str2                  STRING(10)
                    END
strref              &STRING
strref2             &STRING
  CODE  
  
  strref &= grp1
  strref2 &= grp1.str1
  
  STOP(CHOOSE(strref&=strref2)&' '&SIZE(strref)&' '&SIZE(strref2)) !1 30 20

Maybe all what is needed is more documentation in the reference assignment/comparison topic, and some sample code like:

  IF ref1 &= ref2 AND SIZE(ref1) = SIZE(ref2)
  ...

The origin if my question was that the reference equality operator is not documented at all. So, the semantic of this operator is undefined really.

Other problems with the reference equality operator:

  • The operator is not commutative for references of the &WINDOW and &REPORT types:
W    &WINDOW
...
   IF W &= TARGET
    ...
   END

is OK but

   IF TARGET &= W
    ...
   END

produces the compile-time error.

  • If the reference variable in the left side has the type &WINDOW or &REPORT, the TARGET built-in pseudo-variable has the same sense as NULL.