I want to use boost::any to store heterogeneous function pointers. I get an exception when I try to use boost::any_cast to recast to the function pointer.
Is what I want to do even allowed?
.h:
typedef void(*voidFunction)(void);
struct functionInfo{
CString functionName;
boost::any functionPointer;
};
void foo();
int foo2(int a);
.cpp
void foo()
{
;//do something
}
int foo2(int a)
{
;//do something
}
void main()
{
vector<functionInfo> functionList;
functionInfo myInfo;
myInfo.functionName = _T("foo");
myInfo.functionPointer = &foo;
functionList.push_back(myInfo);
myInfo.functionName = _T("foo2");
myInfo.functionPointer = &foo2;
functionList.push_back(myInfo);
voidFunction myVoidFunction = boost::any_cast<voidFunction>(functionList[0].functionPointer);
}
----EDIT----
Ok, you are right, the reason why it acted like this is because foo is a class member function.
Meaning:
void MyClass::foo();
myInfo.functionPointer = &MyClass::foo;
so I needed to typedef:
typedef void(MyClass::*voidClassFunction)(void);
voidClassFunction myVoidFunction = boost::any_cast<voidClassFunction>(functionList[0].functionPointer);
Is what I want to do even allowed?
Absolutely. As long as you cast it back to exactly the type you gave it.
And that's your problem. You don't. foo2 is not a voidFunction. Therefore, you cannot cast it to one.
The purpose of boost::any is to have a void* that is guaranteed to either work correctly according to the C++ standard or throw an exception. The C++ standard allows the conversion of any (non-member) pointer type to a void*. It also allows conversion of a void* back to a type, provided that the type being provided is exactly the same type as the original. If it's not, welcome to undefined behavior.
boost::any exist to prevent undefined behavior by storing type information with the void*. It will rightly throw an exception when you attempt to cast something to the wrong type. As you do here. boost::any is not a way to pretend that types don't exist and to pretend that you can turn anything into something else. It's just a type-safe typeless container. You still need to know what you actually put there.
There is no way to store a list of functions with arbitrary argument lists and call them with the same argument list. The user must provide a function or functor with the right argument list that you expect. boost::bind is a way to adapt a function/functor for a particular argument list, but the user must explicitly use it.
The best you can do is have a list of specific function parameter sets that you accept, stored in a boost::variant object. You can use a visitor to figure out which particular function to call.
Related
X is defined as the following:
struct X
{
Y y;
// more fields...
int a;
};
I have a variable of type X. However, I would like to cast it to the type of its first member, in order to pass that into a function. I know that the C Standard permits it (and I suppose the C++ one does so as well).
In C I would do it like so:
X x;
Y* y = (Y*) x;
doStuff(y);
What type of cast is the right one in C++ for this? static_cast or reinterpret_cast?
None.
You can't mess around with objects using pointers like that. C++ is not C, and these are not "just bytes" (contrary to popular belief).
And you don't need to!
Pass &x.y instead; it's already the Y* you want.
I'd always recommend using static_cast instead of reinterpret_cast in any situation where the static_cast isn't rejected by the compiler. If possible try to avoid doing any casting at all - in this case you probably want: Y* y = &x.y.
To answer the comment:
In this case, I have a PROCESS_MEMORY_COUNTERS_EX
variable. However the WinAPI function GetProcessMemoryInfo takes a
PROCESS_MEMORY_COUNTERS*. The former type starts with the exact same
fields as the latter, and adds a few at the end. The intended usage is
to pass into the function a pointer to the latter type, even if we
hold a pointer to the former (larger) type.
The documentation for GetProcessMemoryInfo() states that the second parameter is:
A pointer to the PROCESS_MEMORY_COUNTERS or PROCESS_MEMORY_COUNTERS_EX
structure that receives information about the memory usage of the
process.
The Win32 API is a C API, and not a C++ one, so you can just use a C style cast here, or preferably a reinterpret_cast to make your intention clearer. I'd expect static_cast to be rejected by the compiler in this case. Note that the third cb parameter is there to tell the function which type of structure you actually provided - it should be set to either sizeof(PROCESS_MEMORY_COUNTERS) or sizeof(PROCESS_MEMORY_COUNTERS_EX).
#FredLarson In this case, I have a PROCESS_MEMORY_COUNTERS_EX variable. However the WinAPI function GetProcessMemoryInfo takes a PROCESS_MEMORY_COUNTERS*. The former type starts with the exact same fields as the latter, and adds a few at the end. The intended usage is to pass into the function a pointer to the latter type, even if we hold a pointer to the former (larger) type.
The cleanest way to accomplish that would be probably (ab)using inheritance. This way, you can have your _EX type share members with the base type while actually being an instance of it.
struct X {
int a;
int b;
};
struct X_EX : public X {
int other_member;
};
void doStuff(X*);
void foo(X_EX* ptr) {
doStuff(ptr);
}
However, do note that "Inherit-to-extend" is seen as a code smell, and something to avoid if possible nowadays. I'd make sure to put a comment explaining why it's necessary here.
I'm trying to implement a C++ class with a value field that can point to anything (a bit like in boost::any). Currently I do the following:
class MyClass {
void* value;
template<typename T>
Myclass(const &T v) {
value = (void*)(new T(v));
}
};
The problem is now to implement a getValue() operation that creates a copy of the inner value with the right type:
template<typename T>
T getValue() {
return *value;
}
Here it cannot work because I'm trying to unreference a void* pointer. I was wondering which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object and an exception is thrown if value was not originally of this type?
Thanks
You cannot dereference a void*, it simply makes no sense. Why not make the class itself generic? Then you can have:
template<typename T>
class MyClass {
T* value;
MyClass(const T& v) {
value = new T(v);
}
T getValue() {
return *value;
}
};
Make sure to create a destructor which deallocates value and also to follow The Rule of Three. You could also make a version of getValue that returns a const T& (const reference to T) to avoid the copy if one is not required.
which cast (static_cast? dynamic_cast? other...) I should use such that *value is properly converted into a T object
If you must do this conversion, then you should use static_cast, which in general is designed to (among other things) reverse any standard conversion. There's a standard conversion from any object pointer type to void*, and your getter reverses it, so use the cast designed for that:
return *static_cast<T*>(value);
You should also either remove the C-style cast from your constructor, or replace that with a static_cast too.
A reinterpret_cast would also work, but is "overkill". In general you should use the cast that is as restrictive as possible while still performing the conversion you need.
and an exception is thrown if value was not originally of this type
You are out of luck there - C++ cannot in general tell what the original type of the object was, once you've cast the pointer to void*. Your code relies on the caller to call getValue with the correct type. For example, consider what happens if the original type was char -- that's just one byte in C++, there is no room set aside for any type information that would allow the compiler to check the cast in getValue.
dynamic_cast does check types in some limited circumstances, but since your template is fully generic, those limited circumstances might not apply.
If you don't like this, you could change your class to store, in addition to the object pointer, a pointer to a type_info object (resulting from a use of the typeid operator). See the standard header <typeinfo>. You could then compare the type_info object for the type T in the constructor, with the type_info object for the type T in getValue, and throw if they don't match.
As you say, your class is intended to be a bit like boost::any, and getValue is like any_cast. You could consult the source and documentation of that class to see the tricks needed to do what you want. If there were a straightforward way to do it, then boost::any would be a straightforward class!
You can't. C++ doesn't provide that sort of mechanism, at least not directly, not for void*. A void* does not have any information that the computer would need to determine what it is, and attempting to "check" if it is a valid whatever-you-cast-it-to is impossible because there aren't particular flags for that.
There are options, though. The first is to use some kind of universal base class, similar to Java's Object, and derive all of your other classes from that. dynamic_cast will now work the way you want (returning NULL if the object is not a valid object of the class you casted it to).
Another is to simply keep track of what type of object it is yourself. That means augmenting the void* with another value that tells you what you need to cast it to.
But really, neither of these things strike me as good ideas. I think there is almost-definitely some other aspect of your design that should be changed rather than using these. Using templates, as #EdS. suggests, is a very good option, for example.
I'm curious why C++ does not define void via :
typedef struct { } void;
I.e. what is the value in a type that cannot be instantiated, even if that installation must produce no code?
If we use gcc -O3 -S, then both the following produce identical assembler :
int main() { return 0; }
and
template <class T> T f(T a) { }
typedef struct { } moo;
int main() { moo a; f(a); return 0; }
This makes perfect sense. A struct { } simply takes an empty value, easy enough to optimize away. In fact, the strange part is that they produce different code without the -O3.
You cannot however pull this same trick with simply typedef void moo because void cannot assume any value, not even an empty one. Does this distinction have any utility?
There are various other strongly typed languages like Haskell, and presumably the MLs, that have a value for their void type, but offer no valueless types overtly, although some posses native pointer types, which act like void *.
I see the rationale for void being unable to be instantiated coming from the C roots of C++. In the old gory days, type safety wasn't that big a deal and void*s were constantly passed around. However, you could always be looking at code that does not literally say void* (due to typedefs, macros, and in C++, templates) but still means it.
It is a tiny bit of safety if you cannot dereference a void* but have to cast it to a pointer to a proper type, first. Whether you accomplish that by using an incomplete type as Ben Voigt suggests, or if you use the built-in void type doesn't matter. You're protected from incorrectly guessing that you are dealing with a type, which you are not.
Yes, void introduces annoying special cases, especially when designing templates. But it's a good thing (i.e. intentional) that the compiler doesn't silently accept attempts to instantiate void.
Because that wouldn't make void an incomplete type, now would it?
Try your example code again with:
struct x; // incomplete
typedef x moo;
Why should void be an incomplete type?
There are many reasons.
The simplest is this: moo FuncName(...) must still return something. Whether it is a neutral value, whether it is the "not a value value", or whatever; it still must say return value;, where value is some actual value. It must say return moo();.
Why write a function that technically returns something, when it isn't actually returning something? The compiler can't optimize the return out, because it's returning a value of a complete type. The caller might actually use it.
C++ isn't all templates, you know. The compiler doesn't necessarily have the knowledge to throw everything away. It often has to perform in-function optimizations that have no knowledge of the external use of that code.
void in this case means "I don't return anything." There is a fundamental difference between that and "I return a meaningless value." It is legal to do this:
moo FuncName(...) { return moo(); }
moo x = FuncName(...);
This is at best misleading. A cursory scan suggests that a value is being returned and stored. The identifier x now has a value and can be used for something.
Whereas this:
void FuncName(...) {}
void x = FuncName(...);
is a compiler error. So is this:
void FuncName(...) {}
moo x = FuncName(...);
It's clear what's going on: FuncName has no return value.
Even if you were designing C++ from scratch, with no hold-overs from C, you would still need some keyword to indicate the difference between a function that returns a value and one that does not.
Furthermore, void* is special in part because void is not a complete type. Because the standard mandates that it isn't a complete type, the concept of a void* can mean "pointer to untyped memory." This has specialized casting semantics. Pointers to typed memory can be implicitly cast to untyped memory. Pointers to untyped memory can be explicitly cast back to the typed pointer that it used to be.
If you used moo* instead, then the semantics get weird. You have a pointer to typed memory. Currently, C++ defines casting between unrelated typed pointers (except for certain special cases) to be undefined behavior. Now the standard has to add another exception for the moo type. It has to say what happens when you do this:
moo *m = new moo;
*moo;
With void, this is a compiler error. What is it with moo? It's still useless and meaningless, but the compiler has to allow it.
To be honest, I would say that the better question would be "Why should void be a complete type?"
I have a template member function with this signature:
template<typename T> void sync(void (*work)(T*), T context);
It can be called with a pointer to a function that accepts an argument of type T*. context is passed to that function. The implementation is this:
template<typename T> void queue::sync(void (*work)(T*), T context) {
dispatch_sync_f(_c_queue, static_cast<void*>(&context),
reinterpret_cast<dispatch_function_t>(work));
}
It uses reinterpret_cast<> and it works. The problem is that the standard doesn't define it very well and it is very dangerous. How can I get rid of this? I tried static_cast but that gave me a compiler error:
static_cast from void (*)(std::__1::basic_string<char> *) to dispatch_function_t (aka void (*)(void *)) is not allowed.
dispatch_function_t is a C type and is the same as void (*)(void*).
I'm not sure I was clear enough. What dispatch_sync_f does is it calls a given callback function and passes the given context parameter to that callback function. (It does that on another thread, although that is out of the scope of this question.)
The reason this is not supported by static_cast is because it is
potentially unsafe. While a std::string* will convert implicitely to
a void*, the two are not the same thing. The correct solution is to
provide a simple wrapper class to your function, which takes a void*,
and static_casts it back to the desired type, and pass the address of
this wrapper function to your function. (In practice, on modern
machines, you'll get away with the reinterpret_cast, since all
pointers to data have the same size and format. Whether you want to cut
corners like this is up to you—but there are cases where it's
justified. I'm just not convinced that this is one of them, given the
simple work-around.)
EDIT: One additional point: you say that dispatch_function_t is a C type. If this is the case, the actual type if probably extern "C" void (*)(void*), and you can only initialize it with functions that have "C" linkage. (Again, you're likely to get away with it, but I've used compilers where the calling conventions were different for "C" and "C++".)
I guess, you are not only casting work to dispatch_function_t, but calling it through dispatch_function_t pointer, aren't you? Such cast itself is valid according to standard, but all you can do with a casted pointer is cast it back to original type. Still your approach should work with most compilers and platforms. If you'd like to implement it so it's more standard conforming you can make a wrapper for your context and work function like this:
template <typename T>
struct meta_context_t
{
T *context;
void (*work)(T*);
};
template <typename T>
void thunk(void *context)
{
meta_context_t<T> *meta_context = static_cast<meta_context_t<T> *>(context);
meta_context->work(meta_context->context);
}
template<typename T> void queue::sync(void (*work)(T*), T context) {
meta_context_t<T> meta_context =
{
&context,
work
};
dispatch_sync_f(_c_queue, static_cast<void*>(&meta_context),
thunk<T>);
}
I can't believe this works or you have a rather narrow definition of "this works" (e.g. you found one particular setup where it seems to do what you think it should do). I'm not clear what dispatch_sync_f() does but I think it is suspicious that it gets a pointer to the local variable context as parameter. Assuming this variable outlives the use of this pointer, there is still a subtle problem which won't get you on most platforms but does get you on some:
C and C++ calling conventions can be different. That is, you cannot cast a pointer to a C++ function to a pointer to a C function and hope for this to be callable. The fix to this problem - and your original question - is, of course, an extra level of indirection: don't dispatch to the function you get as argument but rather dispatch to a C function (i.e. a C++ function declared as extern "C") which takes its own context holding both the original context and the original function and calls the original function. The only [explicit] cast needed is the static_cast<>() restoring a pointer to your internal context from the void*.
Since you seem to implement a template you might need to use another indirection to get rid of this type: I don't thing function templates can be declared extern "C". So you would need to restore the original type somehow e.g. using a base class and a virtual function or something like std::function<void()> holding a readily callable function object doing this conversion (a pointer to this object would be your context).
I believe the cast to/from these two function pointer types is fine:
void(*)(void*)
void(*)(T*)
The problem is that you can't actually use the pointer that you have so cast. It's legal only to cast back to the original type (and those casts are reinterpret_cast, because these are unrelated types). From your code, I can't see how your actual callback function is defined. Why can't you accept a dispatch_function_t as your parameter for queue::sync, rather than casting it?
reinterpret_cast is guaranteed to work when converting from a type T * to void * and back. It is, however, not acceptable to cast from or to a pointer to a base or derived class of T.
The type of work needs to be dispatch_function_t in this case, and the first order of business in that function needs to be the cast from void * to T *. Implicitly casting the argument by using a different argument type and casting the function type is not allowed.
Rationale: the standard allows different pointer representations for different types, as long as all pointer types can be converted to void * and back, so void * is the "most precise" pointer type. A conforming implementation is allowed to clear the bottom-order bits of an uint32_t * if sizeof(uint32_t) > sizeof(char) (i.e. sizeof(uint32_t) > 1) or even shift the pointer value if the machine instructions can utilize these pointers more effectively; on a machine with tagged or shifted pointer values the reinterpret_cast is not necessarily a no-op and needs to be written explicitly.
I'd like to declare a member function pointer in C++, that returns the same member function pointer type
This doesn't work:
class MyClass {
public:
typedef FunctionPtr (MyClass::*FunctionPtr)();
}
Does someone know a solution?
There's no way to achieve exactly that. In fact, member functions make no difference here: there's no way to declare an ordinary function that returns a pointer to its own function type. The declaration would be infinitely recursive.
In case of an ordinary function you can use the void (*)() type as an "universal" function pointer type (just like void * is often used for data types). For member function pointers that would be void (A::*)() type. You'd have to use reinterpret_cast for that purpose though. However, this usage (a round-trip conversion) happens to be the one when the behavior of reinterpret_cast is defined.
Of course, you'll be forced to use casts to convert the pointer to and from that type. AFAIK, there are elegant template-based solutions with an intermediate temporary template object that does the casting.
You might also want to take a look at this GotW entry.
P.S. Note, that using void * type as an intermediate type for function pointers is prohibited by the language. While such illegal use might appear to be "working" with ordinary function pointers, it has absolutely no chance to work with member function pointers. Member function pointers are normally non-trivial objects with size greater than the size of void * pointer.
AndreyT references the best answer at GotW #57, so I might as well replicate it here:
class MyClass {
public:
struct FunctionPtrProxy;
typedef FunctionPtrProxy (MyClass::*FunctionPtr)();
struct FunctionPtrProxy
{
FunctionPtrProxy(FunctionPtr pp ) : p( pp ) { }
operator FunctionPtr() { return p; }
FunctionPtr p;
}
}
What you're trying to do is not possible - the return type of the function is the type of the function itself, which is not yet known, so it leads to an infinite cycle.