epics-base / pvDataCPP

pvDataCPP is an EPICS V4 C++ module
https://epics-base.github.io/pvDataCPP/
Other
6 stars 16 forks source link

document new PVStructure::getAs method #5

Closed mrkraimer closed 9 years ago

mrkraimer commented 9 years ago

Changes in pvDataCPP.html and RELEASE_NOTES

mdavidsaver commented 9 years ago

The new PVStructure::getAs<>() method returns a bare reference, not a shared_ptr<>. So simply replacing getSubField with getAs doesn't work.

The basic formula for replacement would be

PVDoublePtr pvdouble = aStruct->getSubField<PVDouble>("value");
if(pvdouble.get()){ /* it's there */ }
else { /* it's not */ }

goes to

try{
  PVDouble& pvdouble = aStruct->getAs<PVDouble>("value");
  /* it's there */
}catch(...){ /* it's not */ }

Or more interestingly

try{
  double val = aStruct->getAs<pvDouble>("value").get()
             * aStruct->getAs<pvDouble>("aslo").get();
}catch(...){ /* something's not working, set alarm... */ }
mrkraimer commented 9 years ago

I have a concern about returning PVDouble& instead of PVDoublePtr This results in the possibility of using memory that has been released. A simple example is: PVStructurePtr doubleValue = pvDataCreate->createPVStructure( standardField->scalar(pvDouble,"alarm,timeStamp")); PVDouble & pvdouble = doubleValue->getAs("value"); doubleValue = PVStructurePtr(); // this releases memory pvdouble.put(1e5);

This may be a dumb example but more complex code could accidentally do something similar.

mdavidsaver commented 9 years ago

With C/C++ this is always a danger. The idea is to support method chaining where references are very short lived, and creating a lot of temporary shared_ptr<> instances is a waste.

Of course it is always possible to create a shared_ptr<> since PVField inherits enable_shared_from_this<> (ie. has a hidden weak_ptr inside).

ghost commented 9 years ago

In my case, there will be millions of "documents" that I will be doing method chaining. Wouldn't shared_ptr<> be an overkill since these are very short lived(I create these documents and send them across the wire using Matej's pipelining work)? @mdavidsaver :ear:

dhickin commented 9 years ago

I have a concern about returning PVDouble& instead of PVDoublePtr +1

I would prefer a member function that returns a shared pointer. I've discussed this already in the original request (https://github.com/epics-base/pvDataCPP/pull/4).

I've not seen any evidence of performance issues relating to shared_pointers, and, of course, a chain of the form getAs(x.y.z) need only create one shared pointer.