Queue ANY field set to NULL instead of Clear?

Is it valid to NULL the ANY fields in a queue before adding instead of using Clear?

I’d say No. A Q.MyAny&=Null would dispose the value of the previous Queue record’s field. That’s what you do when deleting a queue record. You should Clear(Queue)

I always go double check the Help on ANY because I know it details very well Cear, Null and Queues… excerpt:

Once an ANY variable in a QUEUE has been assigned a value, another simple assignment statement will assign a new value to the ANY. This means the previous value is replaced by the new value. If the first value has already been added to the QUEUE, then that entry will “point at” a value that no longer exists.

Therefore, Queue fields of type ANY must be set to NULLs by executing the CLEAR statement with the QUEUE record structure itself as parameter, i.e. the program must execute CLEAR(Queue), before setting new values of queue field of type ANY for the next ADD() or PUT(). This is because CLEAR for QUEUEs and GROUPs are not applied recursively to the data pointed at from fields of reference types. Therefore, CLEAR(queue) just sets fields of type ANY to NULLs without disposing of their internal data.

In addition, you need to reference assign a NULL to all queue fields of type ANY (Queue.AnyField &= NULL), prior to deleting the QUEUE entry, in order to avoid memory leaks.

https://clarion.help/doku.php?id=any_any_simple_data_type_.htm&s[]=any&s[]=data&s[]=type

I’ve experimented with this extensively, and I’ve essentially confirmed what Carl indicated above. Before adding a new record, use CLEAR(MyQueue). Do not use MyQueue.MyAny &= NULL to clear it.

Similarly, when priming the queue to perform a GET(MyQueue, MyQueue.SomeField), use CLEAR(MyQueue) first, then set the fields to the desired values.

Note that you cannot do a GET(MyQueue, MyQueue.MyAny) or SORT(MyQueue, MyQueue.MyAny) directly like that. Instead, you must use a custom sort function, which can compare the values of MyAny in each passed record parameter.

Here’s an email response from Alexey Solovjev from back in 2000. (The docs have changed since the time of this email). The gist of the email is:

Use CLEAR if you add records to a queue. Use &= NULL before delete record
from a queue.

But here is the whole response:

In fact, this is the same problem. Just at the moment of &= NULL the
VMT address of the ANY’s hidden object has to incorrect value. I have
not found why for a while.

Ok, I know what happens. The documentation is not accurate in explaining
specific rules of works with ANY fields in QUEUEs. It says:

“You must either CLEAR the QUEUE structure or reference assign NULL to the
ANY variable (AnyVar &= NULL) before adding a new QUEUE entry”.

Formally, this is a correct statement. But CLEAR and &= NULL must be used
in mutually exclusive situations. The CLEAR(Queue) or CLEAR(Queue.AnyField)
just clears a space inside queue buffer and not destroys the hidden object
for ANY field. So, the buffer after CLEAR just does not contain a reference
to ANY object. The reference assignment &= NULL to an ANY field both clears
a space in the record buffer occupied by the ANY field AND destroys its
hidden object. Look your code:

q2.a1 &= L2
q2.s = 'L2'
Add(Q2)

All is ok here. The queue stuff has stored a record into memory. Q2.A1
field and its copy in the stored record both reference the same hidden
object.

q2.a1 &= NULL

Disaster! This reference assignment kills the reference stored in the
Q2.A1 field - but the same address has been stored in the queue memory!
After that the stored reference points to destroyed object. The memory
occupied by this object can be re-used by the RTL. So, it’s possible to
say that a copy of the Q2.A1 field stored in the queue memory contains
random value.

q2.a1 &= L3
q2.s = 'L3'
Add(Q2)

I’ve posted several messages to different newsgroups with explanations
where must be used CLEAR and where &= NULL. Last time it was at Friday
to topspeed.products.c5ee (“NEW/DISPOSE help needed!” thread). It would
be nice to have this information in the documentation.

Use CLEAR if you add records to a queue. Use &= NULL before delete record
from a queue.

Alexey Solovjev

2 Likes

Thank you Very MUCH!!!

I wondered about this recently when doing some work with the new scripting language and a GPF occurred when accessing a any in a queue that was set up with &= NULL.

Clearing the field first stopped the GPF but that the code had worked for weeks alerted me to replace &= NULL with Clear.

Fabulous information thank you.

where we want to store data from any source and its not a reference field we now use the Variant field which perhaps uses more memory but it displays in a list where as a ANY does not.

Ha Carl I looked in Clarionfoundry and found a post referencing you on the subject from 2002!
https://www.litreum.com/?articleId=3696