[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-apl] API for GNU APL
From: |
Juergen Sauermann |
Subject: |
Re: [Bug-apl] API for GNU APL |
Date: |
Sun, 22 Feb 2015 11:57:40 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 |
Hi Dirk,
A *Value_P* object is basically a pointer to a *Value* object, pretty
much what is sometimes
called a smart pointer or a shared pointer. The purpose of a *Value_P*
is to delete the *Value* it
points to when the last *Value_P *is deleted.
You should never use references to *Value_P *objects. You may use
references to *const Value &* instead
which can be obtained through *Value_P::getref()*.
A *const Value &* is safe as long as the value exists;
A non-const*Value &* is somewhat dangerous.
A *Value_P *should never be allocated via *new* (and not freed by
*delete*). It should also not be used in the way
suggested by your PCLONE macro below. Instead you can simply copy
*Value_P* objects like integers:
*Value_P value(new Value(...)); // a pointer to a new Value object**
**Value_P copy = value; // a copy of the pointer!*
Also, a *Value* object should never be allocated via *new *except when
constructing a *Value_P* object from it.
Note that above *copy* points to the /same/ *Value* object as *value*
because *copy* is a copy of the pointer and
not a copy of *value* itself. If you want a different value that is
equal to the first then you can use *value->clone() *like this:
*Value_P copy = value->clone(LOC);* // a (deep) copy of the *value*
This is typically needed when *value* is assigned to a variable and then
modified or deleted .
At some point in time you may want to issue the APL command *)CHECK *to
see if your code has created any
stale *Value* objects.
/// Jürgen
On 02/22/2015 10:26 AM, Dirk Laurie wrote:
Hi Jürgen:
I've got code that works except for bugs unconnected with the GNU APL
routines.
I decided to implement the interface as a wrapper for an item of type
`const Value_P&`. API.cc contains the following lines:
// The commented-out variants give segmentation errors, I don't understand why.
// Maybe needed only when `value` is Value*. not when it is already Value_P.
// Jürgen will know.
// #define PCLONE(valuep) valuep
// #define PCLONE(valuep) Value_P(valuep)
#define PCLONE(valuep) *(new Value_P(valuep))
I.e. instead of initializing the item as e.g. `symbol->get_value()`,
I initialize it as `PCLONE(symbol->get_value())`.
I have not laboriously checked in which places this additional `new`
is really necessary, all I know is that it is necessary for at least one
of them.
Best wishes
Dirk