I am trying to do something like
#include <iostream>
using namespace std;
void foo () {
void (*fooptr) (void) = foo;
cout << fooptr << endl;
}
int main () {
void (*fooptr) (void) = foo;
foo ();
return 0;
}
My intent is to see the value of function pointers. If I look up for the address of any function in the main () function it makes sense that the function isn't called, It might have not been allocated the memory in the function call stack. But when I call the function and try to see the value of pointer. It still shows the same result 1. Any explanation?
I might not be printing the address of the called function itself. Is there any pointer like this like we have in classes. So that we can see the address of itself?
The standard stream types don't overload << for function pointers, only for regular pointers. You see the value 1 because a function pointer is implicitly convertible to bool, and there is an overload for bool, so that is chosen.
To print the address, you could convert it to a regular (object) pointer:
cout << reinterpret_cast<void*>(fooptr) << std::endl;
Note that this isn't completely portable: according to the standard, it's conditionally-supported, with an implementation-defined meaning. But it should give the expected address on any sensible implementation on mainstream platforms that store functions in regular memory. For more portability, you might convert to intptr_t or uintptr_t; but you'd need a bit of extra work if you want it to be formatted like a pointer.
Related
I have a function that takes a string, an array of strings, and an array of pointers, and looks for the string in the array of strings, and returns the corresponding pointer from the array of pointers. Since I use this for several different things, the pointer array is declared as an array of (void *), and the caller should know what kind of pointers are actually there (and hence what kind of a pointer it gets back as the return value).
When I pass in an array of function pointers, however, I get a warning when I compile with -Wpedantic:
clang:
test.c:40:8: warning: assigning to 'voidfunc' (aka 'void (*)(void)') from 'void *' converts
between void pointer and function pointer [-Wpedantic]
gcc:
test.c:40:8: warning: ISO C forbids assignment between function pointer and ‘void *’ [-Wpedantic]
fptr = find_ptr("quux", name_list, (void **)ptr_list,
Here's a test file, which despite the warning does correctly print "quux":
#include <stdio.h>
#include <string.h>
void foo(void)
{
puts("foo");
}
void bar(void)
{
puts("bar");
}
void quux(void)
{
puts("quux");
}
typedef void (* voidfunc)(void);
voidfunc ptr_list[] = {foo, bar, quux};
char *name_list[] = {"foo", "bar", "quux"};
void *find_ptr(char *name, char *names[], void *ptrs[], int length)
{
int i;
for (i = 0; i < length; i++) {
if (strcmp(name, names[i]) == 0) {
return ptrs[i];
}
}
return NULL;
}
int main() {
voidfunc fptr;
fptr = find_ptr("quux", name_list, (void **)ptr_list,
sizeof(ptr_list) / sizeof(ptr_list[0]));
fptr();
return 0;
}
Is there any way to fix the warning, other than not compiling with -Wpedantic, or duplicating my find_ptr function, once for function pointers and once for non-function pointers? Is there a better way to achieve what I'm trying to do?
You can't fix the warning. In fact, in my opinion it should be a hard error since it's illegal to cast function pointers to other pointers because there are architectures out there today where this isn't just a violation of the C standard but an actual error that will make the code not work. Compilers allow it because many architectures get away with it even though those programs will crash badly on some other architectures. But it's not just a theoretical standard violation, it's something that causes real bugs.
For example on ia64 function pointers are (or at least used to be last time I looked) actually two values, both necessary to make function calls across shared libraries or a program and a shared library. Likewise, the common practice to cast and call function pointers to functions returning a value to a pointer to a function returning void because you know you'll ignore the return value anyway is also illegal on ia64 because that can lead to trap values leaking into registers causing crashes in some unrelated piece of code many instructions later.
Don't cast function pointers. Always have them match types. This is not just standards pedantry, it's an important best practice.
One solution is to add a level of indirection. This helps with lots of things. Instead of storing a pointer to a function, store a pointer to a struct storing a pointer to a function.
typedef struct
{
void (*ptr)(void);
} Func;
Func vf = { voidfunc };
ptrlist[123] = &vf;
etc.
This is something that has long been broken in the C standard and has never been fixed -- there is no generic pointer type that can be used for pointers to functions and pointers to data.
Before the C89 standard, all C compilers allowed converting between pointers of different types, and char * was generally used as a generic pointer that might point to any data type or any function. C89 added void *, but put in a clause that only object pointers could be converted to void *, without ever defining what an object is. The POSIX standard fixes this issue by mandating that void * and function pointers are safely convertable back and forth. So much code exists that converts function pointers to void * and expects it to work properly. As a result, pretty much all C compilers still allow it, and still generate the correct code, as any compiler that did not would be rejected as unusable.
Strictly speaking, if you want to have a generic pointer in C, you need to define a union that can hold either a void * or a void (*)() and use an explicit cast of the function pointer to the correct function pointer type before calling it.
The language lawyering reason is "because C standard does not explicitly allow it." C11 6.3.2.3p1/p8
1. A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a
pointer to void and back again; the result shall compare equal to the
original pointer.
8. A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall
compare equal to the original pointer. If a converted pointer is used
to call a function whose type is not compatible with the referenced
type, the behavior is undefined.
Notice that a function is not an object in C terminology, hence there is nothing that allows you to convert a pointer to a function to a pointer to void, hence the behaviour is undefined.
Castability to void * is a common extension though. C11 J.5 Common extensions 7:
J.5.7 Function pointer casts
1. A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).
2. A pointer to a function may be cast to a pointer to an object or to void, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4).
This is required by for example POSIX - POSIX has a function dlsym that returns void * but in fact it returns either a pointer to a function or a pointer to an object, depending of the type of the symbol resolved.
As to why this happens - nothing in C standard is undefined or unspecified if the implementations could agree on it. However there were and are platforms where the assumption that a void pointer and function pointer would be of the same width would really make things difficult. One of these is the 8086 16-bit real mode.
And what to use instead then? You can still cast any function pointer to another function pointer, so you can use a generic function pointer void (*)(void) everywhere. If you need both void * and a function pointer, you must use a struct or union or allocate void * to point to the function pointer, or ensure that your code only runs on platforms where J.5.7 is implemented ;)
void (*)() is recommended by some sources too, but right now it seems to trigger a warning in latest GCCs because it doesn't have a prototype.
With some modification you can avoid pointer conversations:
#include <stdio.h>
#include <string.h>
void foo(void)
{
puts("foo");
}
void bar(void)
{
puts("bar");
}
void quux(void)
{
puts("quux");
}
typedef void (* voidfunc)(void);
voidfunc ptr_list[] = {foo, bar, quux};
char *name_list[] = {"foo", "bar", "quux"};
voidfunc find_ptr(char *name, char *names[], voidfunc ptrs[], int length)
{
int i;
for (i = 0; i < length; i++) {
if (strcmp(name, names[i]) == 0) {
return ptrs[i];
}
}
return NULL;
}
int main() {
voidfunc fptr;
fptr = find_ptr("quux", name_list, ptr_list,
sizeof(ptr_list) / sizeof(ptr_list[0]));
fptr();
return 0;
}
As pointed out in other answers you shouldn't be allowed to assign a function pointer to an object pointer such as a void*. But you can safely assign a function pointer to any function pointer. Use reinterpret_cast in C++.
Let me give an example:
typedef void(*pFun)(void);
double increase(double a){return a+1.0;}
pFun ptrToFunc = reinterpret_cast<void(*)(void)>(increase);
the plain
pFun ptrToFunc = increase;
doesn't compile on several compilers.
I'm answering this old question because it seems that one possible solution is missing from existing answers.
The reason why the compiler forbids the conversion is that sizeof(void(*)(void)) can be different than sizeof(void*). We can make the function more generic, so that it can handle entries of any size:
void *find_item(char *name, char *names[], void *items, int item_size, int item_count)
{
int i;
for (i = 0; i < item_count; i++) {
if (strcmp(name, names[i]) == 0) {
return (char*)items + i * item_size;
}
}
return NULL;
}
int main() {
voidfunc fptr;
fptr = *(voidfunc*)find_item("quux", name_list, ptr_list,
sizeof(ptr_list[0]),
sizeof(ptr_list) / sizeof(ptr_list[0]));
fptr();
return 0;
}
Now the find_entry() function doesn't need to directly handle the item at all. Instead it just returns a pointer to the array, and the caller can cast it to a pointer-to-funcpointer before dereferencing it.
(The code snippet above assumes the definitions from original question. You can see full code also here: try it online!)
#include <iostream>
void PrintTheValue(int(*func)(int a));
int main(int argc, char **argv) {
PrintTheValue([](int a) {return a; });
return 0;
}
void PrintTheValue(int(*func)(int a)) {
std::cout << *func << std::endl;
}
In my concept of understanding the func, it would be a pointer to an int passed by value. But in this case I'm passing a lambda which doesn't seem to be called anywhere. (So there isn't any value at all?)
When I run this, it doesn't break the program, but instead printed 00EE6F80.
What does this address mean? I have no idea how to interpret it.
In my concept of understanding the func, it would be a pointer to an int passed by value.
func is a pointer to function, which takes an int and returns int.
But in this case I'm passing a lambda which doesn't seem to be called anywhere.
You're passing a lambda without capturing, which could convert to pointer to function implicitly. In PrintTheValue, *func, i.e dereference on the pointer results in a reference to function, and for being passed to operator<< of std::cout, it converts to function pointer again, then converts to bool with value true (as a non-null pointer), then you should get the result 1 (or true with the usage of std::boolalpha). If you want to call on func you could func(42) (or (*func)(42)).
A lambda is an unnamed function object of the closure type.
The crucial part for this case, this class does not overload the operator<<.
When you dereference the passed lambda in *func, there is no overload for operator<<, so it converts to nearest acceptable result which is bool (at first it reverts to a regular pointer).
The documentation:
Dereferencing a function pointer yields the lvalue identifying the pointed-to function
int f();
int (*p)() = f; // pointer p is pointing to f
(*p)(); // function f invoked through the function lvalue
// But no sense in *p
It should print 1 (since non-null pointer), which it does for me (g++). The language does allow us to do so, but there's no sense in dereferencing a pointer to function without calling the function. All the peculiarities of the function pointers are due to that they have one reasonable usage, so anything you do with them will support that usage - #Pete Becker
For more on Function Pointers check here, it will aid.
I came across something I don't understand well. Let's suppose I want to pass a character pointer to a function that takes a reference to a void pointer.
void doStuff(void*& buffer)
{
// do something
}
I would usually do something like this :
int main()
{
unsigned char* buffer = 0;
void* b = reinterpret_cast<void *>(buffer);
doStuff(b);
return 0;
}
Why it is not possible to directly pass the reinterpret_cast to the function?
int main()
{
unsigned char* buffer = 0
// This generate a compilation error.
doStuff(reinterpret_cast<void *>(buffer));
// This would be fine.
doStuff(reinterpret_cast<void *&>(buffer));
return 0;
}
There must be a good reason behind this behavior but I don't see it.
In the first example, you're actually passing the pointer variable b. So it works.
In the second example, the first reinterpret_cast returns a pointer (by value), which doesn't match the reference the function should get, while the second returns said reference.
As an example to show you how references work, look at these two functions,
void doSomething( unsigned char *ptr );
void doSomethingRef( unsigned char *&ptr );
Say we have this pointer,
unsigned char *a;
Both functions are called the same way,
doSomething( a ); // Passing pointer a by value
doSomethingRef( a );// Passing pointer a by reference
Though it may look like you're passing it by value, but the function takes a reference so it will be passed as a reference.
A reference is similar to a pointer but it has to be initialized with a left value and can't be null.
Having said that, there are much better alternatives to using void* and especially void*&. void* makes code harder to read and easier to shoot yourself in the foot (if anything by making yourself use these strange casts).
As I said in the comments, you could use a template and not bother with void casting.
template< class T > void doStuff( T *&buffer ) {
...
}
Or,
template< class T > T* doStuff( T* buffer ) {
...
}
EDIT: On a side note, your second example is missing a semicolon,
unsigned char* buffer = 0; // Right here
int main()
{
unsigned char* buffer = 0;
void* b = reinterpret_cast<void *>(buffer);
doStuff(b);
return 0;
}
b is a pointer and doStuff(b) is receiving the address of a pointer. The types match, b is of type void*& (*b is of type void*) and doStuff receives a parameter of type void*&.
int main()
{
unsigned char* buffer = 0
// This generate a compilation error.
doStuff(reinterpret_cast<void *>(buffer));
// This would be fine.
doStuff(reinterpret_cast<void *&>(buffer));
return 0;
}
The second call is like the the call from the above function with b as parameter.
The first call is passing simply a void pointer. The types are different, look closer void* is not the same as void*&
This is how you would specify a reinterpret_cast as the function argument directly, without using an intermediate variable. As others have told you, it's bad practice, but I want to answer your original question. This is for educational purposes only, of course!
#include <iostream>
void doStuff(void*& buffer) {
static const int count = 4;
buffer = static_cast<void*>(static_cast<char*>(buffer) + count);
}
int main() {
char str[] = "0123456789";
char* ptr = str;
std::cout << "Before: '" << ptr << "'\n";
doStuff(*reinterpret_cast<void**>(&ptr)); // <== Here's the Magic!
std::cout << "After: '" << ptr << "'\n";
}
Here we have a pointer to char named ptr and we want to wrangle its type to void*& (a reference to a void pointer), suitable for passing as an argument to function doStuff.
Although references are implemented like pointers, they are semantically more like transparent aliases for another value, so the language doesn't provide the kind of flexibility you get for manipulating pointers.
The trick is: a dereferenced pointer converts directly into a correspondingly typed reference.
So to get a reference to a pointer, we start with a pointer to a pointer:
&ptr (char** - a pointer to a pointer to char)
Now the magic of reinterpret_cast brings us closer to our goal:
reinterpret_cast<void**>(&ptr) (now void** - a pointer to a void pointer)
Finally add the dereferencing operator and our masquerade is complete:
*reinterpret_cast<void**>(&ptr) (void*& - a reference to a void pointer)
This compiles fine in Visual Studio 2013. Here is what the program spits out:
Before: '0123456789'
After: '456789'
The doStuff function successfully advanced ptr by 4 characters, where ptr is a char*, passed by reference as a reinterpret_cast void*.
Obviously, one reason this demonstration works is because doStuff casts the pointer back to a char* to get the updated value. In real-world implementations, all pointers have the same size, so you can probably still get away with this kind of manipulation while switching between types.
But, if you start manipulating pointed-to values using reinterpreted pointers, all kinds of badness can happen. You will also probably be in violation of the "strict aliasing" rule then, so you might as well just change your name to Mister Undefined Behavior and join the circus. Freak.
I'm not sure if this is right, but...
I believe it's as simple matching the argument type:
void doStuff(void* buffer) {
std::cout << reinterpret_cast<char*>(buffer) << std::endl;
return;
}
You could do the above and the int main() would compile correctly.
A reference is different from a copy of a value--the difference is that the copied value doesn't necessarily need to live in a variable or in a place in memory--a copied value could be just a stack variable while a reference shouldn't be able to point to an expiring value. This becomes important once you start playing around with reference and value semantics.
tl;dr: Don't mix references and values when casting. Doing operations on a reference is different than doing operations on a value; even if argument substitution is implicitly casted.
In the code below, function-pointer and what i considered as "function-reference" seems to have identical semantics:
#include <iostream>
using std::cout;
void func(int a) {
cout << "Hello" << a << '\n';
}
void func2(int a) {
cout << "Hi" << a << '\n';
}
int main() {
void (& f_ref)(int) = func;
void (* f_ptr)(int) = func;
// what i expected to be, and is, correct:
f_ref(1);
(*f_ptr)(2);
// what i expected to be, and is not, wrong:
(*f_ref)(4); // i even added more stars here like (****f_ref)(4)
f_ptr(3); // everything just works!
// all 4 statements above works just fine
// the only difference i found, as one would expect:
// f_ref = func2; // ERROR: read-only reference
f_ptr = func2; // works fine!
f_ptr(5);
return 0;
}
I used gcc version 4.7.2 in Fedora/Linux
UPDATE
My questions are:
Why function pointer does not require dereferencing?
Why dereferencing a function reference doesn't result in an error?
Is(Are) there any situation(s) where I must use one over the other?
Why f_ptr = &func; works? Since func should be decayed into a pointer?
While f_ptr = &&func; doesn't work (implicit conversion from void *)
Functions and function references (i.e. id-expressions of those types) decay into function pointers almost immediately, so the expressions func and f_ref actually become function pointers in your case. You can also call (***func)(5) and (******f_ref)(6) if you like.
It may be preferable to use function references in cases where you want the &-operator to work as though it had been applied to the function itself, e.g. &func is the same as &f_ref, but &f_ptr is something else.
"Why function pointer does not require dereferencing?"
Because the function identifier itself is actually a pointer to the function already:
4.3 Function-to-pointer conversion
§1 An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function.
"Why dereferencing a function reference doesn't result in an error?"
Basically you can look at defining a reference as defining an alias (alternative name). Even in the standard in 8.3.2 References in part addressing creating a reference to an object, you will find:
"a reference can be thought of as a name of an object."
So when you define a reference:
void (& f_ref)(int) = func;
it gives you the ability to use f_ref almost everywhere where it would be possible to use func, which is the reason why:
f_ref(1);
(*f_ref)(4);
works exactly the same way as using the func directly:
func(1);
(*func)(4);
See here.
The address-of operator acts like you would expect, as it points to a function but cannot be assigned. Functions are converted to function pointers when used as rvalues, which means you can dereference a function pointer any number of times and get the same function pointer back.
As there are good answers from other people here, there is no answer explaining why f_ptr = &&func; does not work. When you apply the addressof operator & to a variable/function, you get its address. The adress itself is an r-value/a temporary variable. You cannot take the address of a temporary.
But it seems that there is a type error. The message implicit conversion from void* is very compiler specific for this code. I guess you are using GCC/Clang. GCC/Clang offers the ability to take the address of labels like &&label. The resulting value is of type void*. Other compilers will output something like cannot take address of temporary or invalid syntax. When using these compilers this kind of error could have been hidden without any warning in special circumstances:
int main() {
int foo = 42;
foo:;
void* a = &foo; // take the address of a variable/function
void* b = &&foo; // take the address of a label
std::cout << *(int*)a << '\n';
goto *b;
};
But who would name everything the same?
Im learning C++ at the moment, and am having some issues with casting pointers. In the first place I am not sure that what I am trying to do is what I want to do..
I am trying to take a function that can return the appropriate pointer to various method pointers based on string parameters, and to then use the method pointer.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef void* (*plugin_function)(void*);
static class Plugin
{
public:
static bool doBoolStuff(){
return true;// A Simple function that returns true
}
};
void* getFunction(string pluginName, string functionName)
{
if(pluginName =="Bool"){
return &Plugin::doBoolStuff;
//If the string is right it should return a method pointer.
//I think that void* has the ability to point to anything, I am trying
//to use that functionality to create a system where I am able to set
//some parameters and get the appropriate method pointer.
}else{
return NULL;
}
}
int main(int argc, _TCHAR* argv[])
{
void* pluginFunction;
pluginFunction = getFunction("Bool","");
if(pluginFunction == &Plugin::doBoolStuff)cout<<"CastSuccesful!"<<endl;
//This section right here is where my code is breaking.
//
// IntelliSense: expression preceding parentheses of apparent call must have
//(pointer-to-) function type
//c:\Users\Walter\Dropbox\Inscription\MethodCasting\MethodCasting\MethodCasting.cpp
//MethodCasting
cout << "Bool function ->"<< pluginFunction()<<endl;
cout << "--------------------------------"<<endl;
system("pause");
}
Any feedback would be helpful.
Edit: Not true, sorry. As #Stephen Lin pointed out, I failed to read the static modifier... So while what you want doesn't work for non-static member functions, it usually does work for static members using reinterpret_cast (this behavior is implementation-defined):
class Plugin {
public:
static bool foo()
{
std::cout << "Foo called!" << std::endl;
return true;
}
};
void *get_func()
{
return reinterpret_cast<void *>(&Plugin::foo);
}
int main()
{
void *pluginFunction = get_func();
(reinterpret_cast<bool (*)()>(pluginFunction))();
return 0;
}
Original post:
You can't. According to this article:
However, there is no way to cast the void * back to a member function pointer that you could actually use.
I've tried it myself. Actually, all of static_cast, reinterpret_cast and even old C-style casts refused to work - neither with void *, nor with bool (*)() (yes, I've even tried to cast from a non-member function pointer type to a member function type)...
Sorry, C++ doesn't seem to allow us to do this.
It depends on your implementation, if you can do this. In portable C++ you can't. And even if you can, you need explicit casts (in this case reinterpret_cast<>) to convert between different pointer types.
Note that this does not extend to real "method" pointers, that is to non-static member function pointers. You cannot convert between member function pointers and either object pointers or ordinary function pointers. The approach I present at the end can be used, if you only have non-static member function pointers.
Portably reinterpret_cast<> can freely convert between function pointer types and object pointer types - although any use of the result except conversion back to the original type is undefined in almost all cases.
For conversions between object pointer types and function pointer types, the C++11 standard says (§5.2.10 [expr.reinterpret.cast]/8):
Converting a function pointer to an object pointer type or vice versa
is conditionally-supported. The meaning of such a conversion is
implementation-defined, except that if an implementation supports
conversions in both directions, converting a prvalue of one type to
the other type and back, possibly with different cv- qualification,
shall yield the original pointer value.
So, it depends on your implementation (and should be documented in its documentation), if casting a function pointer to a void * compiles and back compiles at all. Alas, if it does, you should get the expected behavior.
In your code the casts are missing. You need a cast to the generic type (in your case void*) in getFunction and you need to cast back to the original type in order to call the function. So you will need to know the original type in main():
void* pluginFunction = getFunction("Bool","");
// ....
cout << "Bool function ->"<< (reinterpret_cast<bool (*)()>(pluginFunction))()<<endl;
A more portable solution would be to use an arbitrary function pointer type, for example void (*)() to pass plugin function pointers around, so that you have:
typedef void (*any_func_ptr)();
// If you wanted to use this for non-static member functions, you could do
// struct AnyClass;
// typedef void (AnyClass::*any_memfun_ptr)();
any_func_ptr getFunction(string pluginName, string functionName)
{
if(pluginName =="Bool"){
return reinterpret_cast<any_func_ptr>(&Plugin::doBoolStuff);
}else{
return NULL;
}
}
int main(int argc, char* argv[])
{
any_func_ptr pluginFunction = getFunction("Bool","");
if(reinterpret_cast<bool (*)()>(pluginFunction) ==
&Plugin::doBoolStuff)
cout<<"CastSuccesful!"<<endl;
cout << "Bool function ->"<< (reinterpret_cast<bool (*)()>(pluginFunction))()<<endl;
}