My problem is i need to represent a pointer to class's method like integer number. So it's not problem with functions, for example void (*func)() easy cast to number, but when i trying to cast void (&SomeClass::SomeMethod) to integer with any ways compiles says it's impossible
C-style cast from 'void(ForthInterpreter::*)()' to long is not alowed
I tried (size_t)&ForthInterpreter::CodeFLiteral, static_cast<size_t>(&ForthInterpreter::CodeFLiteral) but i got the same errors. Should to suppose there is a principal differense between pointer to function and method but what is it? And how can i cast it succesfully?
I use clang++ with C++11 version.
for example void (*func)() easy cast to number
No it's not, it just looks like it on your specific machine. There are systems where a pointer is represented as two internal values, for example read about far pointers.
Not to mention the 64-bit problems you're inviting, long is different types in x64 on gcc and cl for example, two very main-stream compilers.
when i trying to cast void (&SomeClass::SomeMethod) to integer with any ways compiles says it's impossible
Absolutely, because not only a class member pointer has the same problem as above, but it absolutely requires a pointer to the object instance itself (usually passed as a register, and again usually ecx or rcx). There's no way you can represent that in a more portable way than a pointer to the correct type.
i need to represent a pointer to class's method like integer number
No you don't, you just want to. There's a difference there. The solution is to adapt to what is possible instead.
A pointer-to-member is not just a simple pointer, it is much more complex. Depending on compiler implementation, it could be 2 pointers, one to the object and one to the method. Or it could be an object pointer and an offset into a method table. And so on.
As such, a pointer-to-member simply cannot be stored as-is in an integer, like you are attempting to do. So you need to find another solution to whatever problem you are trying to solve by storing a pointer inside an integer.
Related
I want to do something like this in a well-defined manner:
struct S
{
static some_integral_type f() noexcept
{
return some_cast<...>(&f);
}
};
The integer can be signed or unsigned. The result should be the same as the casts of object pointers to uintptr_t or intptr_t produce. AFAIK casts to those are not guaranteed to be possible for function pointers. Even casts to uintmax_t and intmax_t might not work for all I know.
I need this so I can produce a unique "handle" from a function pointer, that I can then use in a switch statement.
In general, no.
First, member-function-pointers (and member-pointers) are hairy beasts the standard says very little about.
So, let's ignore them for now.
Next, it might not even be possible to round-trip plain old function-pointers through void*, and the standard only defines a type for round-tripping data-pointers through integers, if the implementation supports such:
(u)intptr_t.
Naturally, if your implementation has a large enough integer-type, you can manually do it by reading the pointer as an unsigned char[] and combining it to a single numeric value, the operation then being reversible.
Be aware that equal function-pointers can result in different numbers if you go that route though, as the same pointer can have multiple possible representations (for example padding bytes, non-value-bits, segmentation)...
You can attempt to select an integer of the same size as the function pointer with a metafunction- the required size being sizeof(void(*)()). However, there's no guarantee that any such integer type exists.
Realistically speaking, casting it to void* or intptr_t is gonna work on pretty much all the mainstream platforms.
Taken from Can std::hash be used to hash function pointers?
In a previous attempt I attempted to cast the function pointer to
void*, which isn't allowed and doesn't compile (see:
https://isocpp.org/wiki/faq/pointers-to-members#cant-cvt-memfnptr-to-voidptr
for details). The reason is that a void* is a data pointer, while a
function pointer is a code pointer.
I'm dealing with some code that uses an external library in which you can pass values to callbacks via a void* value.
Unfortunately, the previous person working on this code decided to just pass integers to these callbacks by casting an integer to a void pointer ((void*)val).
I'm now working on cleaning up this mess, and I'm trying to determine the "proper" way to cast an integer to/from a void*. Unfortunately, fixing the use of the void pointers is somewhat beyond the scope of the rework I'm able to do here.
Right now, I'm doing two casts to convert from/to a void pointer:
static_cast<int>(reinterpret_cast<intptr_t>(void_p))
and
reinterpret_cast<void *>(static_cast<intptr_t>(dat_val))
Since I'm on a 64 bit machine, casting directly ((int)void_p) results in the error:
error: cast from 'void*' to 'int' loses precision [-fpermissive]
The original implementation did work with -fpermissive, but I'm trying to get away from that for maintainability and bug-related issues, so I'm trying to do this "properly", e.g. c++ casts.
Casting directly to an int (static_cast<int>(void_p)) fails (error: invalid static_cast from type 'void*' to type 'int'). My understanding of reinterpret_cast is that it basically just causes the compiler to treat the address of the value in question as the cast-to data-type without actually emitting any machine code, so casting an int directly to a void* would be a bad idea because the void* is larger then the int (4/8 bytes respectively).
I think using intptr_t is the correct intermediate here, since it's guaranteed to be large enough to contain the integral value of the void*, and once I have an integer value I can then truncate it without causing the compiler to complain.
Is this the correct, or even a sane approach given I'm stuck having to push data through a void pointer?
I think using intptr_t is the correct intermediate here, since it's guaranteed to be large enough to contain the integral value of the void*, and once I have an integer value I can then truncate it without causing the compiler to complain.
Yes, for the reason you mentioned that's the proper intermediate type. By now, if your implementation doesn't offer it, you probably have more problems than just a missing typedef.
Is this the correct, or even a sane approach given I'm stuck having to push data through a void pointer?
Yes, given the constraints, it's quite sane.
You might consider checking the value fits instead of simply truncating it upon unpacking it from the void* in debug-mode, or even making all further processing of that integer use intptr instead of int to avoid truncation.
You could also consider pushing a pointer to an actual int instead of the int itself though that parameter. Be aware that's less efficient though, and opens you to lifetime issues.
Based on your question, I am assuming that you call a function in some library, passing it a void*, and at some point later in time, it calls one of your functions, passing it that same void*.
There are basically two possible ways to do this; the first is through explicit casting, as you showed in your current code.
The other, which Deduplicator alluded to, is a little less efficient, but allows you to maintain control of the data, and possibly modify it between when you call the library function, and when it calls your callback function. This could be achieved with code similar to this:
void callbackFunction(void* dataPtr){
int data = *(int*)dataPtr;
/* DO SOMETHING WITH data */
delete dataPtr;
}
void callLibraryFunction(int dataToPass){
int* ptrToPass = new int(dataToPass);
libraryFunction(ptrToPass,callbackFunction);
}
Which one you should use depends on what you need to do with the data, and whether the ability to modify the data could be useful in the future.
"Is this the correct, or even a sane approach given I'm stuck having to push data through a void pointer?"
Well, regarding correct and sane its seriously debatable, especially if you are the author of the code taking the void* in the interface.
I think using intptr_t is the correct intermediate here, since it's guaranteed to be large enough to contain the integral value of the void*, and once I have an integer value I can then truncate it without causing the compiler to complain.
Yes, that's the right type to use with a reinterpret_cast<intptr_t>, but you'll need to be sure, that a intptr_t pointer type has been passed in, and the address is valid and doesn't go out of scope.
It's not so unusual to stumble over this problem, when interacting with c API's, and these are offering callbacks, that allow you to pass in user-data, that will be handled transparently by them, and never are touched, besides of your entry points1.
So it's left up to the client code being sure about how that void* should be re-interpreted safely.
1) A classical example for this kind of situation, is the pthread_create() function
You have little choice but to use static and reinterpret cast here. Casting to an int will result in loss of precision, which is never ideal. Explicitly casting is always best avoided, because sooner or later what is being casted can change and there will be no compiler warnings then. But in this case you understandably have no choice. Or do you?
You can change the callback definitions on your side to be intptr_t or long int rather than void*, and it should then work and you will not have to do any type casts...
For object pointers, we have std::intptr_t and std::uintptr_t from <cstdint>, but those don't need to fit either the function pointers nor the member function pointers. Once could write a metaprogram to find the right fit among the arithmetic types and use the correct alignment, but AFAIK no arithmetic type is guaranteed to fit. One could use an additional level of indirection and use an ordinary pointer to object. One could use an array, say char[], with an appropriate alignment. What does the standard say? Is an arithmetic type, that fits either of the two pointer types, guaranteed to exist?
EDIT:
I need this to pass a pointer into Javascript, disguised as a value of arithmetic type, then pass it back into C++, where I'd convert the value back into a pointer.
I technically won't answer your question, because I think you're asking the wrong one.
Here are the main problems with what you're doing:
Never try to store an address directly in an integral data type, you have no guarantee that it'll work.
Don't store pointers to your data in other places (e.g. files, network, other programs), there's no guarantee that the pointed data will exist when that value is needed.
Store your pointers in a local container and pass around an identifier to the right pointer.
For example, you could use a std::map<int, boost::any> for that and give the scripting language the integer key.
This fixes both mentioned issues.
I had always thought that checking the pointer after casting a void* to a struct* was a valid way to avoid invalid casts. Something like
MyStructOne* pStructOne = (MyStructOne*)someVoidPointer;
if(!pStructOne)
return 0;
It appears that this is not the case as I can cast the same data to two different structs and get the same valid address. The program is then happy to populate my struct fields with whatever random data is in there.
What is a safe way of casting struct pointers?
I can't use dynamic_cast<> as it's not a class.
Thanks for the help!
If you have any control over the struct layout you can put your own type enumeration at the front of every struct to verify the type. This works in both C and C++.
If you can't use an enumeration because not all types are known ahead of time, you can use a GUID. Or a pointer to static variable or member that is unique per struct.
You can use dynamic_cast with structs or classes, as long as it has a virtual method. I would suggest you redesign your broader system to not have void*s anywhere. It's very bad practice/design.
There is no "safe way of casting" in general, because casting pointers is inherently an unsafe procedure. Casting says that you know better than the type system, so you can't expect the type system to be of any help after you started casting pointers.
In C++, you should never use C-style casts (like (T) x), and instead use the C++ casts. Now a few simple rules let you determine whether casting a pointer or reference is OK:
If you const_cast in the bad direction and modify the object, you must be sure that the object is actually mutable.
You can only static_cast pointers or references within a polymorphic hierarchy or from/to void pointer. You must be sure that the dynamic type of the object is a subtype of the cast target, or in the case of void pointers that pointer is the address of an object of the correct type.
reinterpret_cast should only be used to or from a char * type (possibly signed or unsigned), or to convert a pointer to and from an (u)intptr_t.
In every case, it is your responsibility to ensure that the pointers or references in question refer to an object of the type that you claim in the cast. There is no check that anyone else can do for you to verify this.
The (C-style) cast you are using is compile-time operation - that is to say that the compiler generates instructions to modify the pointer to one thing so that it points to another.
With inheritance relationships, this is simply addition or subtraction from the pointer.
In the case of your code, the compiler generates precisely no code whatsoever. The cast merely serves to tell the compiler that you know what you're doing.
The compiler does not generate any code that checks the validity of your operation. If someVoidPointer is null, so will be pStructOne after the cast. \
Using a dynamic_cast<>() doesn't validate that the thing being casted is actually an object at all - it merely tells you that an object with RTTI is (or can be converted to) the type you expect. If it's not an object to start with, you'll most likely get a crash.
There isn't one. And frankly, there can't be.
struct is simply an instruction for the compiler to treat the next sizeof() bytes in a particular semantic fashion - nothing less, nothing more.
You can cast any pointer into any pointer - all that changes is how the compiler would interpret the contents.
Using dynamic_cast<> is the only way, but it invokes RTTI (run type type information) to consider the potential legality of the assignment. Yeah, it's no longer an reinterpret_cast<>
It sounds like you want to make sure the object passed as a void* to your function is really the type you expect. The best approach would be to declare the function prototype with MyStructOne* instead of void* and let the compiler do the type checking.
If you really are trying to do something more dynamic (as in different types of objects can be passed to your function) you need to enable RTTI. This will allow you to interrogate the passed in object and ask it what type it is.
What is a safe way of casting struct pointers?
First, try to avoid needing to do this in the first place. Use forward declarations for structs if you don't want to include their headers. In general, you should only need to hide the data type from the signature if a function could take multiple types of data. The example for something like that is a message passing system, where you want to be able to pass arbitrary data. The sender and receiver know what types they expect, but the message system itself doesn't need to know.
Assuming you have no other alternatives, use a boost::any. This is essentially a type-safe void*; attempts to cast it to the wrong type will throw an exception. Note that this needs RTTI to work (which you generally should have available).
Note that boost::variant is a possibility if there is a fixed, limited set of possible types that can be used.
Since you have to use void*, your options are:
create a single base class including a virtual destructor (and/or other virtual methods) and use that exclusively across the libev interface. Wrap the libev interface to enforce this, and only use the wrappers from your C++ code. Then, inside your C++ code, you can dynamic_cast your base class.
accept that you don't have any runtime information about what type your void* really points to, and just structure your code so you always know statically. That is, make sure you cast to the correct type in the first place.
use the void* to store a simple tag/cookie/id structure, and use that to look up your real struct or whatever - this is really just a more manual version of #1 though, and incurs an extra indirection to boot.
And the direct answer to
What is a safe way of casting struct pointers?
is:
cast to the correct type, or a type you know to be layout compatible.
There just isn't any substitute for knowing statically what the correct type is. You presumably passed something in as a void*, so when you get that void* back you should be able to know what type it was.
I'm writing a delegate class for educational purposes and have run into a little problem. The delegate must be able to call not only functions but also member methods of objects, which means that I need to store a pointer to a method:
void (classname::*methodPtr)(...);
And I need to store pointers to methods from different classes and with different argument lists. At first I just wanted to cast the method pointer to void *, but the compiler dies with an invalid cast error. Turns out that sizeof(methodPtr) == 8 (32-bit system here), but casts to unsigned long long also fail (same compiler error - invalid cast). How do I store the method pointer universally then?
I know it's not safe - I have other safety mechanisms, please just concentrate on my question.
You don't. You use run-time inheritance, if you need abstraction, and create a derived class which is templated on the necessities, or preferably, just create a plain old functor via the use of a function. Check out boost::bind and boost::function (both in the Standard for C++0x) as to how it should be done- if you can read them past all the macro mess, anyway.
You better listen to DeadMG. The problem is, that the size of a member pointer depends on the class type for which you want to form the member pointer. This is so, because depending on the kind of class layout (for example if the class have virtual bases and so on) the member pointer has to contain various offset adjustment values - there is no "one size fits all" member pointer type you can count on. It also means, that you can not assume to have a "castable" integral type which can hold every possible member function pointer.