Reputation: 850
void f(string str,int i )
{
cout<<str.c_str()<<endl;
cout<<i<<endl;
}
typedef void (*PF)(int i,string str);
int _tmain(int argc, _TCHAR* argv[])
{
PF pf=(PF)(void*)&f;
pf(10,string()); //runtime-error
return 0;
}
Due to some needs, I need to call the function f
using the address of f
which data type has been erased (such as the code above). But this solution may cause the insecure function call because the data type can't be checked during the compiling.
Is there some ways to let the compiler to report an error when the the type of parameters are different from arguments'?
Something like this:
void f(T1 i,T2 j)
{
T1 p* = new i.real_type; //if i.real_type is different from T1, it will lead a compiling
....
}
I appreciate that very much.
Upvotes: 1
Views: 193
Reputation: 21721
Depending on the variety of function types you have, you add something for test or debug builds:
// Once off init call
DEBUG_INSERT (&f, INT_STRING);
...
DEBUG_CHECK_FUNC (pf, INT_STRING);
pf(10,string()); //runtime-error
I'm pretty sure that with some boost and/or c++11 magic you could remove the need to have a "KIND" and have that deduced implicitly from the original function type. You could probably end up with your call looking as follows:
CHECKED_CALL (pf, 10, string ());
Where in release builds it just calls the function with the arguments and in debug builds you get the checking too.
Upvotes: 0
Reputation: 474266
Is there some ways to let the complier to report a error when the the type of parameters are different from arguments'.
How could it know? You subverted the type system (that's what casts to void*
s do). You told the C++ compiler to pretend that a function pointer was a pointer to anything, then you told it to pretend that this pointer to anything was a pointer to a different type of function.
The compiler has no way of knowing what the original type was. All it knows is that there's a void*
, and you asked to convert it to something. In order to allow void*
to work at all, the C++ language doesn't require the compiler to magically know where a void*
came from and what it used to be. Therefore, you can cast it to anything, but the specification states that if what you cast it to isn't the original type, you get undefined behavior.
The type system in C++ is what allows the compiler to detect when you've done something wrong. By subverting it, and subsequently doing it wrong, you have given up all rights to live in a rational universe. You told the compiler, "I know what I'm doing", then shot yourself in the foot.
The best you can do is use Boost.Any to store your function pointer. Any attempt to cast it to anything except what was originally stored in it will throw an exception. At runtime, of course.
Upvotes: 0
Reputation: 27038
No. There is no safe way to "get the type" from void*. There is likely a clean way to solve your actual problem so that void* is not needed. I suggestiv you post a new question there you explain your specific task.
Upvotes: 0
Reputation: 283793
The only run-time type information available in C++ is typeid
and dynamic_cast
, and they only work on polymorphic types (class types with virtual functions). Function pointers don't store the necessary information.
Really, you should just avoid casting function pointers. The only place a function pointer case is ever necessary is on the return value from GetProcAddress
or dlsym
.
Upvotes: 1