I'm working on a C++ API which exports several classes from a DLL.
A public class interface should follow the following conventions:
All functions return an error code.
Output parameters are used for additional return values.
Pass by pointer is used for Output parameters.
Pass by const reference is used for Input parameters (pass by value for primitive types).
When the client should take ownership of output parameter shared_ptr is used, otherwise a normal pointer.
Example interface:
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
ErrorCode SetSomething(int i);
ErrorCode IsSomethingSet(bool* ask);
ErrorCode DoSomething();
ErrorCode GetSomething(ObjectPtr* outObj);
}
Example usage:
ErrorCode res;
ObjectPtr obj;
res = myApiClass->GetSomething(&obj);
GetSomething implementation:
ErrorCode APIClass::GetSomething(ObjectPtr* outObj)
{
ObjectPtr temp(new Object(), CleanUpFunction<Object>);
// Do something with object temp.
...
*outObj= temp;
return OK;
}
Is it save to use a shared_ptr in this way or are there possible issues I should be aware of?
This is fine, but I'd ask whether a shared pointer is really necessary in this case. Mostly because you can't release a pointer from a shared_ptr in any sane way... this can lead to problems later. And shared_ptr really means unspecified or shared ownership of the underlying resource.
I typically document the function and use something like:
// Caller must delete the outObj once done.
ErrorCode APIClass::GetSomething( Object* & outObj )
{
// I use auto_ptr so I can release it later...
// Mostly I hate auto_ptr, but for this its invaluable.
auto_ptr<Object> obj( new Object );
...
outObj = obj.release();
return OK;
}
This way it is up to the client what they want to store the pointer into, and it is clear that ownership of the object passes to the caller.
Client code can then use an appropriate container.
Object * obj_raw;
ErrorCode ec = apiClass.GetSomething( obj_raw )
if( ec!=OK ) { .. do something with ec .. }
shared_ptr<Object> obj( obj_raw );
or
auto_ptr<Object> obj( obj_raw );
or
scoped_ptr<Object> obj( obj_raw);
etc.
Note that this can be made neater if you change your function definition to:
// Caller must delete the return value.
// On error, NULL is returned and e filled in appropriately.
Object* APIClass::GetSomething( ErrorCode & e )
{
auto_ptr<Object> obj( new Object );
..
e = OK;
return obj.release();
}
//Now using it looks like this:
ErrorCode ec;
shared_ptr<Object> obj( apiObject.GetSomething(ec) );
if(!obj)
{
.. do something with ec ..
}
Related
I'm trying to implement a simple GetOrCreate() method - get an object by key, or create a new one if not already exists. So far no brainer. I also would like my function's return value to be a Status. So I created the following:
Status GetOrCreate(KeyType key, ObjectType* object) {
Status s = OK;
decltype(my_map)::iterator iter;
bool inserted_new;
std::tie(iter, inserted_new) = clients_.insert(key, ObjectType(...));
if (inserted_new) {
// s = ... Initialize the new ObjectType ...
}
*object = iter->second;
return s;
}
And calling the function:
ObjectType result(...);
Status s = GetOrCreate(key, &result);
Now, I feel it's somewhat wasteful, because:
There is an unnecessary copy in *object = iter->second;
There is an unnecessary object initialization in ObjectType result(...);
(Not sure. I may be wrong, or perhaps c++11 elides them. Still I would like to explicitly know what I'm doing).
So I created a version #2 which passes ObjectType** object instead. I'm not afraid of double pointers but might require more explaining to my reviewers. *& is not an option due to project code-style.
Seems like a very basic design problem, but I'm scratching my head. So, is it justified to use double pointer here? Is there a better approach?
I'm using C++11 (most of my experience is 98).
How about using smart pointers:
std::pair<Status, std::shared_ptr<ObjectType>> GetOrCreate(KeyType key) {
Status s = OK;
decltype(my_map)::iterator iter;
bool inserted_new;
std::tie(iter, inserted_new) = clients_.insert(key, ObjectType(...));
if (inserted_new) {
// s = ... Initialize the new ObjectType ...
}
return std::pair<Status, std::shared_ptr<ObjectType>>(s, iter->second);
}
And use it like this:
auto ret = GetOrCreate(key, result);
// ret->first is Status
// ret->second is std::shared_ptr<ObjectType>
So I've been working on memory management and have a particular issue when it comes to moving objects that contain function objects that wrap lambda's that capture data. Suppose the following example:
typedef std::function < void( int ) > funcType;
class Something
{
private:
int _myNum = 0;
public:
funcType GetSetIt( )
{
return [&] ( int a )
{
_myNum = a;
};
}
void SeeIt( )
{
std::cout << _myNum << std::endl;
}
int GetIt( )
{
return _myNum;
}
};
And the following operations:
auto destination = ( Something* ) malloc( sizeof( Something ) );
auto alt = ( funcType* ) malloc( sizeof( funcType ) );
auto size = sizeof( funcType );
auto s = new Something( );
auto setIt = s->GetSetIt( );
setIt( 10 );
s->SeeIt( );
auto a = s->GetIt( );
memcpy( destination, s, sizeof( Something ) );
memset(s, 0, sizeof( Something ) );
memcpy( alt, &setIt, sizeof( funcType ) );
memset( &setIt, 0, sizeof( funcType ) ); // point 1
(*alt)( 15 );
destination->SeeIt( );
auto b = destination->GetIt( );
A quick explanation:
Create a new Something and call all of it's members to make sure it's working correctly. Then move it to a new location and delete/clear where it used to exist. Also move the function object to a new location and clean up after. Then, using pointer's to the new locations, call the function object and the methods on the object.
The first issue is that everything is moving along smoothly until I memset the original location of the function object. If you comment out that line (noted with // point 1) you'll notice it does not crash.
This is a little strange to me, but I don't fully understand how function objects are laid out in memory and was hoping for a little light to be shed in that area. I would assume that if I block-copied the entire object to another area and cleared the old space (not deleting it because it's on the stack) that it and all of it's references would be preserved.
The second issue, assuming you've commented out the memset line is that "expected results" are not the same as "desired results". I expect that calling alt will set _myNum on s to 15, and it does. But I want to update alt's pointer to Something (which I usually refer to as it's this pointer) to point to destination. How can I achieve that? Can it be done dependably across compilers? I've been worried that, although I could conceivably find where it's stored and update the value, the solution won't be solid because lambda's can be implemented in a variety of ways across compilers and there may be some "magic" at hand.
Any help or insight into these issues is greatly appreciated. If I'm not clear on what's going on, comment and I'll provide more detail where needed. Thanks in advance!
function is not trivially copyable (3.9p9, 9p6) so you cannot copy it with memcpy. Use the is_trivially_copyable trait to detect whether a type is trivially copyable.
If you want to "move" an object of a non-trivially copyable type from one location to another, use placement new with its move constructor and perform a destructor call on the previous location:
new (*buf) T(std::move(obj));
obj.~T();
You should use placement new and ensure the setter is taken from the copied object:
#include <functional>
#include <iostream>
// ...
int main() {
char source[sizeof(Something)];
char source_setter[sizeof(funcType)];
Something* src = new (source) Something;
// Get the setter from the source object.
funcType* src_setter = new (source_setter) funcType(src->GetSetIt());
(*src_setter)(0);
char destination[sizeof(Something)];
char destination_setter[sizeof(funcType)];
Something* dst = new (destination) Something(*src);
// Get the setter from the destination object.
funcType* dst_setter = new (destination_setter) funcType(dst->GetSetIt());
(*dst_setter)(1);
src->SeeIt();
dst->SeeIt();
src_setter->~funcType();
src->~Something();
dst_setter->~funcType();
dst->~Something();
}
Ok so I'm wanting to write a precise 'mark and sweep' garbage collector in C++. I have hopefully made some decisions that can help me as in all my pointers will be wrapped in a 'RelocObject' and I'll have a single block of memory for the heap. This looks something like this:
// This class acts as an indirection to the actual object in memory so that it can be
// relocated in the sweep phase of garbage collector
class MemBlock
{
public:
void* Get( void ) { return m_ptr; }
private:
MemBlock( void ) : m_ptr( NULL ){}
void* m_ptr;
};
// This is of the same size as the above class and is directly cast to it, but is
// typed so that we can easily debug the underlying object
template<typename _Type_>
class TypedBlock
{
public:
_Type_* Get( void ) { return m_pObject; }
private:
TypedBlock( void ) : m_pObject( NULL ){}
// Pointer to actual object in memory
_Type_* m_pObject;
};
// This is our wrapper class that every pointer is wrapped in
template< typename _Type_ >
class RelocObject
{
public:
RelocObject( void ) : m_pRef( NULL ) {}
static RelocObject New( void )
{
RelocObject ref( (TypedBlock<_Type_>*)Allocator()->Alloc( this, sizeof(_Type_), __alignof(_Type_) ) );
new ( ref.m_pRef->Get() ) _Type_();
return ref;
}
~RelocObject(){}
_Type_* operator-> ( void ) const
{
assert( m_pRef && "ERROR! Object is null\n" );
return (_Type_*)m_pRef->Get();
}
// Equality
bool operator ==(const RelocObject& rhs) const { return m_pRef->Get() == rhs.m_pRef->Get(); }
bool operator !=(const RelocObject& rhs) const { return m_pRef->Get() != rhs.m_pRef->Get(); }
RelocObject& operator= ( const RelocObject& rhs )
{
if(this == &rhs) return *this;
m_pRef = rhs.m_pRef;
return *this;
}
private:
RelocObject( TypedBlock<_Type_>* pRef ) : m_pRef( pRef )
{
assert( m_pRef && "ERROR! Can't construct a null object\n");
}
RelocObject* operator& ( void ) { return this; }
_Type_& operator* ( void ) const { return *(_Type_*)m_pRef->Get(); }
// SS:
TypedBlock<_Type_>* m_pRef;
};
// We would use it like so...
typedef RelocObject<Impl::Foo> Foo;
void main( void )
{
Foo foo = Foo::New();
}
So in order to find the 'root' RelocObjects when I allocate in 'RelocObject::New' I pass in the 'this' pointer of the RelocObject into the allocator(garbage collector). The allocator then checks to see if the 'this' pointer is in the range of the memory block for the heap and if it is then I can assume its not a root.
So the issue comes when I want to trace from the roots through the child objects using the zero or more RelocObjects located inside each child object.
I want to find the RelocObjects in a class (ie a child object) using a 'precise' method. I could use a reflection approach and make the user Register where in each class his or her RelocObjects are. However this would be very error prone and so I'd like to do this automatically.
So instead I'm looking to use Clang to find the offsets of the RelocObjects within the classes at compile time and then load this information at program start and use this in the mark phase of the garbage collector to trace through and mark the child objects.
So my question is can Clang help? I've heard you can gather all kinds of type information during compilation using its compile time hooks. If so what should I look for in Clang ie are there any examples of doing this kind of thing?
Just to be explicit: I want to use Clang to automatically find the offset of 'Foo' (which is a typedef of RelocObject) in FooB without the user providing any 'hints' ie they just write:
class FooB
{
public:
int m_a;
Foo m_ptr;
};
Thanks in advance for any help.
Whenever a RelocObject is instantiated, it's address can be recorded in a RelocObject ownership database along with sizeof(*derivedRelocObject) which will immediately identify which Foo belongs to which FooB. You don't need Clang for that. Also since Foo will be created shortly after FooB, your ownership database system can be very simple as the order of "I've been created, here's my address and size" calls will show the owning RelocObject record directly before the RelocObject instance's that it owns.
Each RelocObject has a ownership_been_declared flag initialized as false, upon first use (which would be after the constructors have completed, since no real work should be done in the constructor), so when any of those newly created objects is first used it requests that the database update it's ownership, the database goes through it's queue of recorded addresses and can identify which objects belong to which, clear some from it's list, setting their ownership_been_declared flag to true and you will have the offsets too (if you still need them).
p.s. if you like I can share my code for an Incremental Garbage Collector I wrote many years ago, which you might find helpful.
To overcome the impossibility of giving C library a callback to C++ member function, wanted to implement something like this:
SomeObject* findSomeObjectByHandlePointer(datahandle *dh) { }..
by using a map, which contains addresses of *datahandle as an index, and addresses of *SomeObject's as value.
When SomeObject is created, it produces a group of datahandle's, which are unique for the object. Then, it passes a pointer to *datahandle and static callback function to C library, then C library calls back and returns a pointer to datahandle, that in turn can be associated back with a SomeObject.
Which types can you recommend for storing pointer values in a map besides safe but slow <string, SomeObject*>?
This answer tells me to avoid using auto_ptr too.
Normally, C-like callbacks take a void* user_data parameter, which allows you to pass in anything you want:
void c_func(void (*fptr)(void*), void* user_data){
// do some stuff
fptr(user_data);
}
Now, simply make the following static member function:
class A{
public:
static void c_callback(void* my_data){
A* my_this = static_cast<A*>(my_data);
// do stuff with my_this
}
};
Edit: According to #Martin's comment, you may get unlucky with a static member function. Better use an extern "C" function:
extern "C" void c_callback(void* my_data){
// same as static method
}
And pass that + your A instance to that c_func:
int main(){
A a;
c_func(&A::c_callback,&a);
}
Or if that A instance needs to outlive the current scope, you need to somehow save the heap-allocated pointer somewhere and delete it manually later on. A shared_ptr or the likes won't work here, sadly. :(
On your problem of storing pointer in a map, that's not a problem at all, see this little example on Ideone.
I think this will suffice. It is what we use:
class datahandle;
class SomeObject;
typedef std::map<datahandle*, SomeObject*> pointer_map;
pointer_map my_map;
SomeObject* findSomeObjectByHandlePointer( datahandle *dh) {
pointer_map::const_iterator ff = my_map.find(dh);
if (ff != my_map.end()) {
return ii->second;
}
return NULL;
}
Often callback functions have an extra parameter of type void* which you can use to pass in any additional data you might need. So if you want to use a member function as your callback, you pass in a pointer to the object casted to void* and then cast it back and call the member function in your callback function.
If you have many reads and less writes, you could use vector as a set. It is very common, because lower_bound is more effective than map and use less space from memory:
typedef std::pair<std::string,Your_pointer> your_type;
bool your_less_function( const your_type &a, const your_type &b )
{
// your less function
return ( a < b );
}
...
std::vector<your_type> ordered-vector;
When you add values:
...
ordered-vector.push_back(value)
...
// Finally. The vector must be sorted before read.
std::sort( ordered-vector.begin(), ordered-vector.end(), your_less_function );
When ask for data:
std::vector<your_type>::iterator iter = std::lower_bound( ordered-vector.begin(), ordered-vector.end(), value, your_less_function );
if ( ( iter == ordered-vector.end() ) || your_less_function( *iter, value ) )
// you did not find the value
else
// iter contains the value
I was commenting on an answer that thread-local storage is nice and recalled another informative discussion about exceptions where I supposed
The only special thing about the
execution environment within the throw
block is that the exception object is
referenced by rethrow.
Putting two and two together, wouldn't executing an entire thread inside a function-catch-block of its main function imbue it with thread-local storage?
It seems to work fine, albeit slowly. Is this novel or well-characterized? Is there another way of solving the problem? Was my initial premise correct? What kind of overhead does get_thread incur on your platform? What's the potential for optimization?
#include <iostream>
#include <pthread.h>
using namespace std;
struct thlocal {
string name;
thlocal( string const &n ) : name(n) {}
};
struct thread_exception_base {
thlocal &th;
thread_exception_base( thlocal &in_th ) : th( in_th ) {}
thread_exception_base( thread_exception_base const &in ) : th( in.th ) {}
};
thlocal &get_thread() throw() {
try {
throw;
} catch( thread_exception_base &local ) {
return local.th;
}
}
void print_thread() {
cerr << get_thread().name << endl;
}
void *kid( void *local_v ) try {
thlocal &local = * static_cast< thlocal * >( local_v );
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
return NULL;
}
int main() {
thlocal local( "main" );
try {
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
pthread_t th;
thlocal kid_local( "kid" );
pthread_create( &th, NULL, &kid, &kid_local );
pthread_join( th, NULL );
print_thread();
}
return 0;
}
This does require defining new exception classes derived from thread_exception_base, initializing the base with get_thread(), but altogether this doesn't feel like an unproductive insomnia-ridden Sunday morning…
EDIT: Looks like GCC makes three calls to pthread_getspecific in get_thread. EDIT: and a lot of nasty introspection into the stack, environment, and executable format to find the catch block I missed on the first walkthrough. This looks highly platform-dependent, as GCC is calling some libunwind from the OS. Overhead on the order of 4000 cycles. I suppose it also has to traverse the class hierarchy but that can be kept under control.
In the playful spirit of the question, I offer this horrifying nightmare creation:
class tls
{
void push(void *ptr)
{
// allocate a string to store the hex ptr
// and the hex of its own address
char *str = new char[100];
sprintf(str, " |%x|%x", ptr, str);
strtok(str, "|");
}
template <class Ptr>
Ptr *next()
{
// retrieve the next pointer token
return reinterpret_cast<Ptr *>(strtoul(strtok(0, "|"), 0, 16));
}
void *pop()
{
// retrieve (and forget) a previously stored pointer
void *ptr = next<void>();
delete[] next<char>();
return ptr;
}
// private constructor/destructor
tls() { push(0); }
~tls() { pop(); }
public:
static tls &singleton()
{
static tls i;
return i;
}
void *set(void *ptr)
{
void *old = pop();
push(ptr);
return old;
}
void *get()
{
// forget and restore on each access
void *ptr = pop();
push(ptr);
return ptr;
}
};
Taking advantage of the fact that according to the C++ standard, strtok stashes its first argument so that subsequent calls can pass 0 to retrieve further tokens from the same string, so therefore in a thread-aware implementation it must be using TLS.
example *e = new example;
tls::singleton().set(e);
example *e2 = reinterpret_cast<example *>(tls::singleton().get());
So as long as strtok is not used in the intended way anywhere else in the program, we have another spare TLS slot.
I think you're onto something here. This might even be a portable way to get data into callbacks that don't accept a user "state" variable, as you've mentioned, even apart from any explicit use of threads.
So it sounds like you've answered the question in your subject: YES.
void *kid( void *local_v ) try {
thlocal &local = * static_cast< thlocal * >( local_v );
throw local;
} catch( thlocal & ) {
print_thread();
return NULL;
}
==
void *kid (void *local_v ) { print_thread(local_v); }
I might be missing something here, but it's not a thread local storage, just unnecessarily complicated argument passing. Argument is different for each thread only because it is passed to pthread_create, not because of any exception juggling.
It turned out that I indeed was missing that GCC is producing actual thread local storage calls in this example. It actually makes the issue interesting. I'm still not quite sure whether it is a case for other compilers, and how is it different from calling thread storage directly.
I still stand by my general argument that the same data can be accessed in a more simple and straight-forward way, be it arguments, stack walking or thread local storage.
Accessing data on the current function call stack is always thread safe. That's why your code is thread safe, not because of the clever use of exceptions. Thread local storage allows us to store per-thread data and reference it outside of the immediate call stack.