I have the following function
static void p (){
}
I want to pass a function pointer to p into function x.
void x(void * ptr){
}
I am trying the following, and it is not working.
...
x(ptr);
Note x and p are in different classes.
I am getting the following compiling error.
invalid conversion from 'void (*)()' to 'void*' [-fpermissive]
It needs to be:
void x(void(*function)())
{
// Whatever...
}
If you're using C++11 you can std::function:
void x(std::function<void()> function)
{
// Whatever
}
Let's take a look at the error message:
invalid conversion from 'void (*)()' to 'void*' [-fpermissive]
It means that void* (a data pointer) is the type specified in x,
but void (*)() (a function pointer) is being passed instead.
So change x to
void x(void (*ptr)())
{
}
The answer is in the error message. void* is not a pointer to function, void(*)() (for example) is. You should rewrite x as follows :
void x(void (*ptr)()) {
}
A pointer-to-function is written this way :
Ret (*name)(Params)
Where
Ret is the pointee's return type
name is the name of the pointer
Params is the list ofthe pointee's parameters, as you would write them in its declaration.
Example :
double (*ptr)(int, float)
...can point to a function taking an int and a float and returning a double.
void* is not a function pointer, it's a void pointer.
To declare a function pointer, use void (*ptr)().
We can do some ugly pointer magic, like this:
static void function1( char* c ) {
printf( "%s", c );
}
void function2( void* ptr ) {
void(* func)(char*) = (void(*)(char*))ptr;
func( "a" );
}
int _tmain(int argc, _TCHAR* argv[])
{
void* f = function1;
function2( f );
return 0;
}
This is bad, but it works in such situations.
Related
How I can change the value of p to 1 passing it as an argument to a recursive function.
This is my code:
class Solution
{
void g(int n,int k,int *p){
if(k==0) return;
if(k%n==0) g(n,k-1,1);
cout<<p<< endl;
g(n,k-1,p+1);
}
public:
int josephus(int n, int k)
{ int p=1;
g(n,k,&p);
return p;
}
};
I get this errors:
prog.cpp: In member function void Solution::g(int, int, int*):
prog.cpp:14:21: error: invalid conversion from int to int* [-fpermissive]
if(k%n==0) g(n,k-1,1);
^
prog.cpp:12:9: note: initializing argument 3 of void Solution::g(int, int, int*)
void g(int n,int k,int *p){
The error says you cannot pass an int as a parameter to a function when it expects an int *.
There is also a logical bug in your code:
g(n,k-1,p+1);
This recursive call increments the pointer value, which makes it point past the passed in object, since the function was called like this:
{ int p=1;
g(n,k,&p);
Since your function takes an int *, you need to dereference the pointer to manipulate the referenced object. So, you probably intend to increment *p and then make the recursive call:
++*p;
g(n,k-1,p);
To address the compilation error, you probably intended to assign 1 to the int object and make the recursive call.
if(k%n==0) {
*p = 1;
g(n,k-1,p);
}
In C/C++, we can declare/define a type of pointer to function, and then declare/define some variables of this type.
But I think it is ambiguity.
For example:
typedef void ( *pFunc )();
// typedef void ( aFunc )();
void theFunc() {
cout << "theFunc has been called successfully." << endl;
};
int main() {
pFunc pf0 = theFunc;
pFunc pf1 = &theFunc;
pf0();
( *pf0 )();
pf1();
( *pf1 )();
};
Theoretically, only pFunc pf1 = &theFunc; and (*pf1)(); are legal, but all of above can pass through compilation.
In Pascal syntax, we need to define vars of function or vars of pointer to a function respectively, and the meaning of them are different and much clearer(at least I think so)!
Moreover, we can't declare/define a var of function instead of a var of pointer to function!
I tried follows and get failed.
typedef void ( aFunc )();
aFunc af0 = theFunc;
If with other types such as int/double, there are very strict syntax that restricts us to use them correctly. (If int* is not same as int, why is *pf0 is same as pf0?!)
So, Can I think it is a bug of C/C++ standard?
Some declared types:
// decltype of theFunc is void ()
// decltype of &theFunc is void (*) ()
// decltype of *theFunc is void (&) ()
Now, concerning your code, since a function is implicitly convertible to a pointer to that function, we have:
using pFunc = void(*)();
using rFunc = void(&)();
pFunc p_fct = &theFunc; // no conversion
pFunc p_fct = theFunc; // conversion lvalue to pointer
pFunc p_fct = *theFunc; // conversion lvalue reference to pointer
rFunc r_fct = *theFunc; // no conversion
rFunc r_fct = theFunc; // conversion lvalue to lvalue reference
rFunc r_fct = &theFunc; // ERROR: conversion pointer to lvalue reference not allowed
So far the conversions. Now, any object of type pFunc or rFunc is a callable object. Also, note that both (*p_fct) and (*r_fct) are of type rFunc. Therefore, you can call your function as described in the question:
p_fct(); // callable object of type pFunc
r_fct(); // callable object of type rFunc
(*p_fct)(); // callable object of type rFunc
(*r_fct)(); // callable object of type rFunc
Note that the following is equivalent to the above:
using Func = void ();
Func* p_fct = &theFunc; // no conversion
Func& r_fct = *theFunc; // no conversion
p_fct(); // callable of type Func* or pFunc
r_fct(); // callablel of type Func& or rFunc
EDIT To answer to the question: "why them was arranged in this way" from the below comment: functions cannot be copied (as explained in #JohnBurger's answer). This is why your code:
typedef void ( aFunc )();
aFunc af0 = theFunc;
doesn't work. As explained above, you can do the following though:
typedef void ( aFunc )();
aFunc* af0 = &theFunc; // or theFunc, or even *theFunc
Or you could do this:
auto myFct = theFunc;
But keep in mind that the decltype of myFct is still void (*)().
Ignore functions for a second: think about a struct.
You can have a struct, or a pointer to a struct:
typedef struct {
int x;
int y;
} Point;
Point origin = { 0, 0 };
Point here = { 1, 1 };
Point there = { 2, 2 };
int main() {
Point centre = origin;
Point *myPoint = &origin;
centre = here;
myPoint = &here;
centre = there;
myPoint = &there;
} // main()
There are three global Points: origin, here and there.
main() has two variables: centre and myPoint.
centre copies the value of origin, here, and there.
myPoint points to origin, here, and there - it does not copy them.
There is a large difference between these two ideas: one copies the whole object, while the other only points to the other object.
Now think about functions. Functions are defined by the compiler in code, and can never be copied. So it makes no sense to have function variables - how large would they be? The only sensible idea is a pointer-to-function - so that is all that the C language provides.
If you want to define a C function typedef, use the following syntax:
// Fn is a function that accepts a char and returns an int
int Fn(char c);
// FnType is the type of a function that accepts a char and returns an int
typedef int FnType(char c);
// Here is the definition of Fn
int Fn(char c) {
return c + 1;
} // Fn(c)
// Now here is how you can use FnType
int main() {
FnType *fn = &Fn;
return fn('A');
} // main()
I think that I have found the answer.
Indeed c++ standard has offered a method to declare a type of function without the help of pointers.
example:
#include <functional>
using AFunc_t = function<void( int )>;
void theFunc( int );
AFunc_t afunc = theFunc;
I hope this could help someone.
why I need intermediate variable to pass my return pointer by reference instead of just using the function that returns that pointer ?
This doesn't compile
int main ()
{
testfunc(getpointer());
return 0;
}
error: C2664: 'void testfunc(int *&)': cannot convert argument 1 from 'int *' to 'int *&'
and this compiles
int main ()
{
int *i = getpointer();
testfunc(i);
return 0;
}
my two functions
void testfunc(int *& i) // I have to use this interface
{
cout << i[0] <<endl;
}
int* getpointer()
{
int * arr1 = new int[1];
arr1[0]=10;
return arr1;
}
The C++ language prohibits binding a non-const reference to a temporary. In this case, the simple fix is to make testfunc take a const reference to an int*.
In C++ using clang++, is it possible to overload a method according to address-space qualifiers on the implicit ‘this’ parameter? If so, what is the syntax?
This source suggests that I can place the address-space qualifier after the parameter list but before the curly braces (similar to using the const qualifier on 'this'). I tried the following, but it failed; clang thinks I'm trying to set an address space of the method, rather than of 'this':
// Does not work.
struct SomeClass
{
// method for 'this' in default address space
void doit();
// method for 'this' in address space 300.
void doit() __attribute__((address_space(300)); // clang rejects this syntax
}
The closest I have found is that clang lets me overload a method according to the address spaces of its explicit formal parameters (not 'this'). For example, the code below will print “1\n2\n”.
// Similar, but does not solve my problem:
#include <cstdio>
struct SomeClass
{
void doit(void *v) { printf("1\n"); }
void doit(void __attribute__((address_space(300))) *v) { printf("2\n"); }
};
int main(int argc, char **argv)
{
SomeClass SC;
SC.doit( (void*) 0 );
SC.doit( (void __attribute__((address_space(300))) *) 0 );
return 0;
}
typedef void (*callable_function)(double);
void call_function(callable_function func)
{
func(3.0);
}
class Foo;
union converter {
callable_function func;
void (Foo::*foo_func)(void);
};
class Foo {
private:
double d;
public:
Foo(void) : d(0.0)
{
converter c;
c.foo_func = &Foo::set_double;
call_function(c.func);//I know i can call the function directly, but that is not what i want to achieve
}
void set_double(double value)
{
d = value;
}
};
void main(void)
{
Foo foo;
}
When trying to execute the code above, i get a heap corruption error in the line:
d = value;.
Probably because the function being called is the class function, not the member function.
But if i try to change this line: c.foo_func = &Foo::set_double; to c.foo_func = &this->set_double;, i get this compiler error:
error C2276: '&' : illegal operation on bound member function expression
Question #1: Is there any way to convert the pointer(casting maybe) from void(Foo::*)(void) to void()(void) or to fix the compiler error?
pointer to "free" function and pointer to member function in C++ have different sizes.
That means you technically can cast pointer to free function to void* ptr as usually they have the same size but you cannot cast member function pointer to void* or other free function - you will get what you've got.
Check this: Pointers to members representations