Can we emplace small object on void*? - c++

Suppose there's API like below:
typedef void callback_t(void* data);
void addCallback(handle_t h, callback_t callback, void* data);
I'd like to wrap this API to a higher order C++ interface:
template<class F, bool emplace = IsEmplaceable<F>::value>
struct MakeCallback;
class Handle
{
template<class F>
void addCallback(F f)
{
::addCallback(_h, MakeCallback<F>::f, MakeCallback<F>::create(f));
}
handle_t _h;
};
so that the user can pass any callable object (e.g. lambda function).
I'd like to apply small object optimization to avoid dynamic alloc (e.g. for empty lambdas), the trait IsEmplaceable<F> decides whether F can be emplaced in a void*.
For F that is not emplaceable, MakeCallback can be implemented like below:
template<class F>
struct MakeCallback<F, false>
{
static void f(void* data)
{
auto f = static_cast<F*>(data);
(*f)(status);
delete f;
}
static void* create(F& f)
{
return new F(std::move(f));
}
};
For F that is emplaceable, how could I properly implement the following?
template<class F>
struct MakeCallback<F, true>
{
static void f(void* data)
{
// from void* to F
}
static void* create(F& f)
{
// form F to void*
}
};
More basically, can a void* hold a non-address value if we don't use it as a pointer? will it be UB?

A very big warning should be mentioned before even attempting the code shown in this answer. Doing this is most likely very very undefined and not portable behavior. I would highly suggest not doing this as it could very well break a long time into the future and you will have a very hard time finding out why.
That being said, it appears to work on at least my compiler. Results may vary for other compilers. I use a union to convert between a class instance and a void *, don't know of any other clean way to do this. This should work as long as sizeof( Class ) <= sizeof( void * ), but I make no guarantees on behavior with different compilers or even with the exact same compiler I used on my exact same setup.
#include <iostream>
using namespace std;
class Small {
public:
int i;
};
void *castToVoid( Small& s ) {
union {
Small s;
void *p;
} un;
un.s = s;
return un.p;
}
Small castToSmall( void *p ) {
union {
Small s;
void *p;
} un;
un.p = p;
return un.s;
}
int main( ) {
Small s;
s.i = 100;
void *p = castToVoid( s );
s.i = 200;
cout << p << endl; // Prints 0x64
Small s2 = castToSmall( p );
cout << s2.i << endl; // Prints 100
}
or this example for converting to/from a void *
void *castToVoid( Small& s ) {
void **p = reinterpret_cast< void ** >( &s );
return *p;
}
Small castToSmall( void *p ) {
Small *s = reinterpret_cast< Small * >( &p );
return *s;
}

It's implementation-defined behavior according to the C++ standard (draft N3797).
§ 3.7.4.2/p4
Indirection through an invalid pointer value and passing an invalid
pointer value to a deallocation function have undefined behavior. Any
other use of an invalid pointer value has implementation-defined
behavior.
footnote 38:
Some implementations might define that copying an invalid pointer
value causes a system-generated runtime fault
§ 3.7.4.3/p4
An implementation may have relaxed pointer safety, in which case the
validity of a pointer value does not depend on whether it is a
safely-derived pointer value. Alternatively, an implementation may
have strict pointer safety, in which case a pointer value referring to
an object with dynamic storage duration that is not a safely-derived
pointer value is an invalid pointer value unless the referenced
complete object has previously been declared reachable (20.7.4) [...] It is implementation
defined whether an implementation has relaxed or strict pointer safety.
(emphasis mine)
So it is safe if the implementation has relaxed pointer safety, and we can use the union trick as shown in the answer from #Smith_61 to avoid strict aliasing.

Related

Preserve access privileges when using '->' operator

I have two classes,
template<class Type>
class SafePtr {
public:
SafePtr() {}
~SafePtr() {}
void Lock(Type* data, void* key)
{
if (!pKey)
{
pKey = key;
pData = data;
}
}
Type* Unlock(void* key) const
{
if (key == pKey)
return pData;
}
Type* operator->()
{
return pData;
}
private:
Type* pData = nullptr;
void* pKey = nullptr;
};
template<class Type>
class SafePtrArray {
public:
SafePtrArray() {}
~SafePtrArray() {}
template<class... Args>
SafePtr<Type> CreatePtr(Args&&... args)
{
Type* data = new Type(args...);
ptrs.insert(ptrs.end(), data);
SafePtr<Type> ptr;
ptr.Lock(data, this);
return ptr;
}
Type* UnlockPtr(const SafePtr<int>& ptr)
{
return ptr.Unlock(this);
}
void Destroy(const SafePtr<int>& ptr)
{
Type* pointer = ptr.Unlock(this);
for (auto itr = ptrs.begin(); itr != ptrs.end(); itr++)
{
if ((*itr) == pointer)
{
delete pointer;
ptrs.erase(itr);
}
}
}
private:
std::vector<Type*> ptrs;
};
The goal is to protect a pointer so that the user can access its members but not get to manipulate its actual pointer (mainly delete it prematurely). And also I need to store all the pointers in an array so that when the parent object destroys, I can automatically destroy all the allocated pointers
For this I use two classes, SafePtr and SafePtrArray. SafePtrArray creates and stores the pointers and wraps them in the SafePtr and returns it to the user. SafePtr is just a wrapper and should not let the user get access to the underlying pointer but will allow them to access its members.
It works fine at first but soon I found this error,
int main()
{
SafePtrArray<int> ptr;
auto pInt = ptr.CreatePtr();
int* i = pInt.operator->(); // Users can get access to the underlying pointer using this.
ptr.Destroy(pInt);
}
Is there a way to prevent users from getting access to the underlying type and prevent them from manipulating the pointer while having the privilege to access its members?
I still think you try to solve a problem that has more to do with possible flaws in the design of the API/of the code, the documentation, or with the lack of C++ knowledge of the one using it, with a "solution" that has more cons than pros.
If a C++ programmer does not know what ownership is or does not respect it and blindly deletes objects or frees the memory of pointers, then there will be much bigger concerns. You likely will move the problem just to a different part of the code.
Having that said, the closest you can do to not expose the pointer right now is something like this:
(The code is just a proof of concept, so things like call might need to be improved)
#include <iostream>
#include <string>
struct Test {
void foo(int x, int y, std::string str) {
std::cout << x << " " << y << " " << str << std::endl;
}
double test = 0.5;
};
template <typename T>
struct Ptr {
template <auto M, typename... Args>
auto call(Args... args) {
return (obj.*M)(std::forward<Args>(args)...);
}
template <auto M>
auto get() {
return (obj.*M);
}
protected:
T obj;
};
int main() {
Ptr<Test> p;
p.call<&Test::foo>(1, 2, "hello");
std::cout << p.get<&Test::test>() << std::endl;
return 0;
}
But I still don't think that this is a good approach.
And a user can still mess around with the code and do something bad like:
int main() {
Ptr<Test> p;
delete &p;
return 0;
}
Or this, which for sure is undefined behavior, but that does not really matter as deleting a not owned object will also result in undefined behavior at some point:
template<typename T>
struct Ptr {
protected:
T *obj;
}
template<typename T>
struct Ptr2 {
public:
T *obj;
};
int main()
{
Ptr<Test> p;
Ptr2<Test> *p2 = reinterpret_cast<Ptr2<Test>*>(&p);
std::cout << p2->obj << std::endl;
}
So there is no protection again such things.
Besides the shown code, there is a proposal for reflection that is feature complete now, which would allow getting information about the members of a type, but this was not added to c++20, and one for metaclasses which is also not in the standard yet.
With these two proposals, you might be able to implement something better useable. But my concerns about the benefits of this remain.
Is there a way to prevent users from getting access to the underlying type and prevent them from manipulating the pointer while having the privilege to access its members?
Under certain conditions, no, this is not possible. If the underlying Type is a standard layout class then providing access to the first non-static non-bitfield data member breaks your goal. (Caveat: providing access to just the value of the member is a different story.) The address of that member can be converted to a pointer to the underlying object via reinterpret_cast, which allows calling delete on that pointer. (Well, "allows" in the sense that the call is syntactically valid. Not much else matters for "allows" since we are headed into undefined behavior anyway.)
For classes that are not standard layout, there are probably compiler-specific (non-portable) methods to achieve the same effect (converting the address of a data member into a pointer to the underlying object). There is no reason for a compiler to try actively to thwart such things.
If a programmer is determined to invoke undefined behavior, there is little you can do to stop it.

What is the best practice to consume a pointer returned as an argument

Normally when a pointer to an object is created and returned from a function you consume it using unique_ptr to ensure it is deleted at the end of the scope.
CustomType* GetTheObject(); // Let's say this the function signature and it returns a new object
void Main() {
auto object = make_unique(GetTheObject());
object->DoSomething();
// Then the object is deleted automatically
}
What if the function signature is like this
bool GetTheObject(CustomType** object);
I can imagine a rather verbose way to consume it
void Main() {
// Declare a pointer which we never need
CustomType* object_ptr;
if(GetTheObject(&object_ptr)) {
// Then create a unique_ptr out of it
auto object = make_unique(object_ptr);
object->DoSomething();
// Then the object is deleted automatically
}
}
Is there a better recommended way how to consume an object in this case. I can think about another let's say unique_ptr2 class which implements & operator and then use it like
unique_ptr2 object;
if(GetTheObject(&object)) {
// use it
}
Is there a ready to be used implementation of unique_ptr2 which would allow doing that? It still feel to be not ideal. Is there a better way?
I might be tempted to write code that automates the conversion to/from the unique ptr. We generate a new function from our existing function "automatically" that has the same signature, but T* return values are unique_ptr<T> and T** arguments are unique_ptr<T>* arguments.
Then we inject the conversion boilerplate using RAII and template metaprogramming.
A ptr_filler is a RAII type that converts a unique_ptr<T>* into a T**:
template<class T>
struct ptr_filler {
std::unique_ptr<T>* output = nullptr;
T* temporary = nullptr;
ptr_filler( std::unique_ptr<T>* bind ):output(bind) {}
operator T**()&&{return &temporary;}
~ptr_filler() {
if (temporary)
*output = std::unique_ptr<T>(temporary);
}
};
ret_converter_t does a type conversion from the C-style API to a C++ unique-ptr API:
template<class T> struct ret_converter { using type=T; };
template<class T> using ret_converter_t = typename ret_converter<T>::type;
template<class T> struct ret_converter<T*> { using type=std::unique_ptr<T>; };
get_converter_t converts argument types from the C-style API, to one that fills unique ptrs via a ptr_filler:
template<class T> struct get_converter { using type=T; };
template<class T> using get_converter_t = typename get_converter<T>::type;
template<class T> struct get_converter<T**> { using type=ptr_filler<T>; };
Finally, call deduces its arguments from the function pointer you pass it, then converts the arguments and retval to use unique ptr memory management, and calls the function f for you:
template<class R, class...Args>
ret_converter_t<R> call( R(* f)(Args...), get_converter_t<Args>... args ) {
return static_cast<ret_converter_t<R>>( f( std::forward<decltype(args)>(args)... ) );
}
now we can:
struct CustomType {
int x;
};
CustomType* GetTheObject(int x) { return new CustomType{x}; }
bool MakeTheObject( CustomType** pp, int a, int b ) { *pp = new CustomType{a+b}; return a>b; }
we can do:
int main() {
std::unique_ptr<CustomType> ptr;
std::cout << call( MakeTheObject, &ptr, 2, 1 ) << " = 1\n";
std::cout << ptr->x << " = 3\n";
ptr = call( GetTheObject, 7 );
std::cout << ptr->x << " = 7\n";
}
You can get fancier with call<MakeTheObject> syntax, but it takes work. This assumes that the API you are wrapping is an C-ish API but returns new'd objects.
Live example.
I would think that returning a std::unique_ptr would be safer than returning a raw pointer, since returning a raw pointer risks the calling code accidentally leaking the object. I'd recommend doing it this way:
#include <iostream>
#include <memory>
class CustomType
{
// ...
};
std::unique_ptr<CustomType> GetTheObject()
{
if ((rand()%2) != 0) return std::make_unique<CustomType>();
return std::unique_ptr<CustomType>(); // nothing to return, sorry
}
int main(int argc, char ** argv)
{
if (std::unique_ptr<CustomType> p = GetTheObject())
{
std::cout << "Got the object!" << std::endl;
}
return 0;
}
If you have to live with an existing function that you don't like the shape of and can't change, you can hide the ugliness inside a wrapper function and then call the wrapper function instead:
std::unique_ptr<CustomType> PrettyGetTheObject()
{
CustomObject * obj;
if (GetTheObject(&obj)) return std::unique_ptr<CustomObject>(obj);
return std::unique_ptr<CustomType>(); // nothing to return, sorry
}
A possible approach is to use a wrapper function. Example:
bool GetOriginal(char **pptr);
bool GetWrapped(std::unique_ptr<char> * puptr) {
bool result;
if (puptr != nullptr) {
char * cptr;
result = GetOriginal(&cptr);
*puptr = std::make_unique(cptr);
} else {
result = GetOriginal(nullptr);
}
return result;
}
This assumes the commonly used pattern of passing null to avoid getting a pointer to manage (e.g. if you're only interested in the return value).
If passing null to the original function is not part of its api, then you could of course use a reference to a std::unique_ptr instead of a raw pointer.
If you have many such functions you could also write a general wrapper function for that, of course:
template<typename Fn, typename T>
bool wrap(Fn fn, std::unique_ptr<T> * puptr) {
bool result;
if (puptr != nullptr) {
T * cptr = nullptr;
result = fn(&cptr);
*puptr = std::make_unique(cptr);
} else {
result = fn(nullptr);
}
return result;
}
// usage: wrap(GetOriginal, &some_unique_ptr)
If the original function takes more arguments, then use std::bind or a lambda.

Assigning Union's fields

i have created a structure uses an union as its field. Here is a small code example:
#include <iostream>
#include <string>
enum Type
{
STR,
INT
};
struct MyStruct
{
Type type;
union Value
{
std::string str;
int i;
Value(){}
~Value(){};
} value;
void setType(Type type)
{
this->type = type;
}
void setValue(const std::string& data)
{
this->value.str = data;
}
MyStruct(){}
~MyStruct(){}
};
int main()
{
MyStruct my;
my.setType(Type::STR);
my.setValue("Hallo");
std::cout << my.value.str << std::endl;
return 0;
}
Setting Value i got an error (Segmentation fault (core dumped)) What is the right way to do that? Thanks!
Be careful. Non-POD types in unions are asking for trouble. Saying that, this is supported in C++11, provided you only initialise at most one member. That means you'll have to change how things work.
Trivially, to fix your program as it stands right now, you just use placement new:
void setValue(const std::string& data)
{
new (&value.str) std::string(data);
}
But now, if you want to set a different member later, you will need to use placement delete on the string. To achieve that, you need to know that there was a string there to begin with. So you cannot easily separate the setValue from the setType.
One option (not particularly nice) is:
private:
void setType( type ) {
// Destruct existing type
switch( this->type ) {
case STR:
value.str.~std::string();
break;
default:;
}
this->type = type;
}
public:
void setValue( const std::string& data )
{
setType( STR );
new (&value.str) std::string(data);
}
void setValue( int data )
{
setType( INT );
value.i = data;
}
And don't forget to properly destruct the value in ~MyStruct.
Although C++11 does allow you to have classes inside a union, it is generally considered to be bad practice, because it's a minefield of undefined behavior.
If your union's constructor does not construct the union's member which is a class instance -- as is the case with your sample code -- by definition that class instance never gets constructed.
Your code then attempts to use the union's class member. Namely its operator=. Because this class instance has not been constructed, this becomes undefined behavior, which results in your crash.
Stick with PODs in your unions. Less grief.

C++ std containers - polymorphism without pointers. Is it possible?

Is it possible to maintain knowledge of the derived class in any std c++ container without using pointers, dynamically casting return values from the container? I know I can create a vector or what ever of pointers of some base class type, and have them retain their sub classes. But the question is do I have to use pointers?
Example:
struct A {
int x = 0, y = 0, z = 0;
virtual void foo() { cout << "A" << endl; };
};
struct B : public A {
int a = 1, b = 1, c = 1;
virtual void foo() { cout << "B" << endl; };
};
int main() {
<SOMECONTAINER><A> a(2);
a[0] = A();
a[1] = B();
B * p;
B& n = dynamic_cast<B&>(a[1]); // Always throws?
p = dynamic_cast<B*>(&a[1]); // Always zero?
cout << p << endl;
}
Yes, you do have to use pointers. Otherwise, attempting to put a B into a container of A results in slicing: the B gets cut down into an A (this is not limited to containers, the exact same thing happens if you do A a = B() or if you pass a B to a function expecting an A).
When you later take it back out, it's an A that has absolutely no knowledge its lineage includes an illustrious forefather of type B -- and no matter what way you look at an A, you can't make it a B.
I am going to ignore alignment, or rather assume that data after a pointer is sufficiently aligned.
template<class T, unsigned N>
struct poly_anna;
template<class T,unsigned N>
struct poly_bob {
typedef poly_anna<T,N> poly_anna_;
T*(*get)(poly_anna_*) = nullptr;
void(*destroy)(poly_anna_*) = nullptr;
void(*move_to)(poly_anna_ *,poly_anna_*) = nullptr;
void(*copy_to)(poly_anna_ const*, poly_anna_*)=nullptr;
};
template<class T, unsigned N>
struct poly_anna {
private:
poly_bob<T,N> const*bob=nullptr;
char buff[N];
public:
template<class U> static poly_bob<T,N> const* get_bob() {
static poly_bob<T,N> b={
[](poly_anna*a)->T&{ return *(U*)&a->buff[0]; },
[](poly_anna*a){ ((U*)&a->buff[0])->~U(); a->bob = nullptr; },
[](poly_anna*s,poly_anna*d){
if (s->bob==d->bob){
*((U*)&d->buff[0])=std::move(*((U*)&d->buff[0]));
return;
}
if (d->bob != nullptr) {
d->bob->destroy(b);
}
d->store( std::move( *(U*)&s->buff[0] ) );
},
[](poly_anna const* s, poly_anna*d){
if (d->bob == s->bob){
*(U*)&d->buff[0] = *(U const*)&s->buff[0];
return;
}
if (d->bob){ d->bob->destroy(d); }
d->store( *(U const*)*s->buff[0] );
}
};
return &b;
};
template<class U_>
void store(U_&& u){
typedef typename std::decay<U_>::type U;
static_assert( sizeof(U)<=N, "N not large enough" );
if (bob) bob->destroy( this );
bob = get_bob<U>();
new (&buff[0]) U( std::forward<U_>(u) );
}
void reset(){ if (bob) bob->destroy(this); }
T& get() {
return bob->get(this);
}
T const& get() const {
return bob->get(const_cast<poly_anna*>(this));
}
poly_anna( poly_anna const& o ){
if (o.bob) o.bob->copy_to( &o, this );
}
poly_anna( poly_anna && o ){
if (o.bob) o.bob->move_to( &o, this );
}
poly_anna&operator=( poly_anna const& o ){
if (o.bob) o.bob->copy_to( &o, this );
else if (bob) bob->destroy(this);
return *this
}
poly_anna&operator=( poly_anna && o ){
if (o.bob) o.bob->move_to( &o, this );
else if (bob) bob->destroy(this);
return *this
}
poly_anna()=default;
~poly_anna(){if(bob)bob->destroy(this);}
explicit operator bool()const{return bob;}
};
That is my attempt at a polymorphic variant. It stores T and children of T so long as they are no larger than N and can be stored in std containers.
Let me know if it compiles.
You need pointers for virtual member function dispatch.
When you think about it, without pointers, you are left with "by value". Value semantics and and polymorphism don't really make sense together.
A value has a single context / type. It is atomic and simple. WYSIWIG, so to speak. Sure, you can cast it, but then you have ... another value.
There's an oft-quoted programmer proverb: There is no problem which cannot be solved with an additional layer of indirection, except too many layers of indirection.
Putting it into practice, take a look at boost::variant.
If your container stores boost::variants allowing all the (sub-)classes you want to store, you can avoid pointers.
That can be a win, but need not be.
Measure before you commit to such a solution.
I think there are actually two questions here:
Is it possible to get polymorphic semantics in an STL container without using pointers and the associated dynamic allocation?
Is is possible to retain the concrete type of a polymorphic object stored in an STL container?
The answer to 1 is yes, with some effort. As some have mentioned, one way to do this is to use a variant type like boost::variant. The problem with that approach is that you lose the ability to interact naturally with the objects stored in the variant and instead have to write visitors, which have a lot of syntactic overhead.
If the class hierarchy is bounded then a better approach might be to use a variation on boost::variant (no pun intended) specifically designed to preserve polymorphic semantics and its associated syntax. One example might be the emplacer. As noted in dyp's comment above, emplacer is a restricted variant.
As for question 2, I'm not aware of any way to do that without using typeid() or a hand-rolled type system.

C++ pointer argument getting set to NULL just before 'ret' instruction [duplicate]

This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 8 years ago.
I'm having a peculiar issue. I thought I knew a decent amount of C++ but I must be overlooking some nuance?
I've got some templated classes, and essentially all that is happening is based on some condition, an object is being moved from one std::list to another.
The method of focus here is the doAndGet( T *t ). My intent is for t to come in as NULL (or whatever, I really don't care, but it should be NULL or nullptr, and if I end up moving a T element *t from myList to myOtherList, I want T *t to point to the item that was moved.
Now maybe there is something about std::list that I'm not aware of, but when stepping through my code, t gets assigned properly and—originally I thought after the method returned, but later found out that—right before the ret instruction, argument T *t gets set back to NULL
Can any guru shed some light on this issue? It's a real head-scratcher for me...
template<typename T, typename C>
class Base : IsDerivedFrom<T, C>
{
public:
typedef std::list<T*> SpecialList;
virtual bool doAndGet( T* t ) = 0;
protected:
SpecialList myList;
};
template<typename T>
class Derived : public Base<T, Other>, public Other
{
public:
Derived( void );
virtual ~Derived( void );
bool doAndGet( T* t );
protected:
typename Base<T, Other>::SpecialList myOtherList;
};
template<typename T>
bool Derived<T>::doAndGet( T *t )
{
// Nothing to process
if (myOtherList.empty()) {return false;}
t = (*myOtherList.begin());
myOtherList.pop_front();
if (true/* some condition needs to be moved */)
{
t->status = 1;
this->myList.push_back(t);
return true;
} else
{
// Something bad happened...
delete t;
t = nullptr;
return false;
}
}
// Use... (pretend I defined MyOtherClass somewhere, not important)
Derived<MyOtherClass> derivedInstance;
MyOtherClass *t = nullptr;
if ( derivedInstance.doAndGet(t) )
{
// ... Here I should expect `t` to be not `NULL` and not `nullptr`
// This however, is not ever the case in my testing...
}
If you want to pass in a variable to a function and have any changes within that function to be reflected back to the caller, you need to use a reference.
C++, like C, is pass by value, where a function only gets a copy of a variable. C++ has references to allow pass by reference.
In other words, your function signature should be:
bool doAndGet( T* &t );
to state that t is a reference to a T*, allowing changes to reflect back to the original pointer in the caller.
A simpler example follows:
#include <iostream>
static void change (int a, int &b) { a = b = 0; }
int main() {
int a = 42, b = 42;
change (a, b);
std::cout << a << ' ' << b << '\n';
return 0;
}
This outputs 42 0 because the a passed in is pass by value and changes are not reflected back to the caller. The b is passed in as a reference so changes are reflected back.
doAndGet passes its parameter by value. So the parameter in the calling function is not changed.
Simpler example of the same thing:
void func(int x)
{
++x;
}
int main()
{
int y = 5;
func(y);
std::cout << y << "\n"; // outputs 5
}