I'm learning C. I know what the first line is doing; it's making a pointer to a function with no arguments and it returns an int. But wtf is the second doing?
My guess is that it is casting an int into a function? But what does it mean to turn an int into a function?
Also, why does it cause an error when I try to call the function: 'function()'?
int (*function) ();
function = (int (*) ()) (1000);
Overall, the code is nonsense. Where did you get it from?
it's making a pointer to a function with no arguments
Rather, it is making a pointer to a function with obsolete style parameter list.
But wtf is the second doing?
It assigns the function pointer to point at address 1000 (decimal), my means of a cast from int to the function pointer type.
why does it cause an error when I try to call the function: 'function()'?
Likely because there is no such function allocated at address 1000. You might not even have access to that area etc.
learning function pointer is pain in ass.
simple example maybe help for better understand.
suppose you want point to this function:
int sum (int a , int b) {
return a+b;
}
so you need define a pointer with same type:
int *pointerToSum (int, int);
and simply assign it to function:
pointerToSum = ∑
if you want use it:
(*pointerToSum)(3, 5); //8
you can use function-pointer tag to find out more complex answers.
your question delete by people because there is duplicate question asked before.
I implement function-pointer for myself and it's a little complex and you can see in : exercise of function pointer
I wish you the best.
Related
What is the proper C syntax for a function returning pointer to another function (which again may return a pointer to some thrid function etc)? I know that we can define a function as a local variable inside another function (but we need to know the address or it is useless):
int*(*a)(int) = (void*)0;
This is local variable a which represents a function which has int as a parameter and returns pointer to int, while the address of the function is 0. How can I have a function which returns, instead of pointer to int, a pointer to a function requiring char as a parameter and returning a pointer to int? This is what I've tried:
int*(*)(char)(*a)(int) = (void*)0;
But, it is a syntax error. Is there a way to do it, or maybe, the only way is to return void* and then to cast it again to function?
Edit
I am not looking only for a solution which works. I know it can be done using typedef or just by returning a generic pointer and then casting to another function. But, I am writting a code highlighter for C and I want to cover all cases which are defined by ISO C, so I am wondering does ISO C allow double returning functions, if yes, what is the proper syntax, if no, can it be found somewhere in documentation?
You could use typedefs to simplify this (and make sure you can actually understand the code a week later):
typedef int*(*FuncA)(int);
typedef FuncA(*FuncB)();
FuncB a = (void*)0;
Obviously use more descriptive names than I have done here.
int (*)[3] foo (); doesn't work.
How to declare function return pointer to array of 3?
It might not be useful, but I want to know if it's possible.
First, I agree with the other answers that you probably need a typedef or a struct in there to clarify.
If you want to know how to declare the return type, it's
int (*foo(void))[3] {
In the "declaration reflects use" pattern, you can build this up by considering the usage, i.e. how to get from foo's type to the plain type int:
take foo
call it (with no arguments): foo()
dereference the return value: *foo()
add an array index: (*foo())[i]; the parentheses are needed because the postfix syntax would otherwise take precedence over prefix one.
the result is of plain type int
Declaration reflects it:
take foo
call it: foo(void), inserting void to say it's specifically a 0-param function rather than one with an unspecified set of parameters
dereference the function return value: *foo(void)
add an array index: (*foo(void))[3], making the "index" be the size of the array
we got down to the plain type, so declare that the thing you built has that type: int (*foo(void))[3]
Example code:
#include <stdio.h>
int arr[3];
int (*foo(void))[3] {
return &arr;
}
int main (void) {
arr[0] = 413;
arr[1] = 612;
arr[2] = 1025;
printf("%d %d %d\n", (*(foo()))[0], (*(foo()))[1], (*(foo()))[2]);
return 0;
}
Side note: be sure that the array you are returning a pointer to will continue to exist after the function returns.
I'd advise against doing this.
It's often done as a poor workaround for the apparent limitation that C has of not being able to have an array as a return value.
Too often, a dangling pointer will be returned since the programmer will return a pointer to an array in the function that has automatic storage duration. Then this gets hacked to a static which ruins the threading model and breaks all previous returned pointers!
Only slightly better is returning a pointer given to you by a malloc call internal to the function. But then, that burdens (asymmetrically) the caller with having to call free at some point. Eventually your function winds up in some kind of precompiled library which uses a different C runtime to a client. Your malloc and their free no longer match, and you end up with a truck load of undefined behaviour!
Instead of all this, do consider passing the array by pointer on the function parameter list, preferably pre-allocating the memory.
One way is:
typedef int Int_array_3[3];
Int_array_3 * foo(void);
As a rule of thumb, avoid functions passing/returning raw array pointers or function pointers, because such code is a nightmare both to program and read. In this case it would have been
int (*func()) [3]
which is completely unreadable. Just forget about writing such code. Instead, use a typedef to define an array type:
typedef int iarr3_t [3];
And then write a function returning a pointer to such an array:
iarr3_t* func (void);
However, as indicated by other comments and answers, returning an array pointer is usually quite questionable practice to begin with. The need to do so could be an indication of poor program design.
Can someone explain this line by line (character by character maybe, haha)?
typedef int (*funcptr)(); /* generic function pointer */
typedef funcptr (*ptrfuncptr)(); /* ptr to fcn returning g.f.p. */
funcptr start(), stop();
funcptr state1(), state2(), state3();
void statemachine()
{
ptrfuncptr state = start;
while(state != stop)
state = (ptrfuncptr)(*state)();
}
funcptr start()
{
return (funcptr)state1;
}
For example, I would like to know why there are () at the end of line 1. An answer like "that's just how you declare a pointer to a function" would be satisfying, but then when you declare a variable of that type, why only use "funcptr" without the ()?
Lines 4 and 5. Why do you have the () here? Those aren't functions, they're pointers to functions, right?
Line 9. Why doesn't "state" have ()? Still a pointer to a function as are the ones on lines 5 and 6.
Line 9. What is "start" without the ()?
Line 12. WHAT?! (I know what typecasting is. At least I think I do...)
Line 17. Why does "state1" require a typecast? It is of the type it's being cast as already. Or is it because it's missing the ()?
It would really help me to understand these concepts.
PS. This is for a microcontroller I'll use in an electronic Dummy Load I'm designing. Figured it's a good opportunity to learn more about C. The code is from http://c-faq.com/decl/recurfuncp.html
As noted in the question, this comes from the C FAQs web site. The question is:
Q: How can I declare a function that can return a pointer to a function of the same type? I'm building a state machine with one function for each state, each of which returns a pointer to the function for the next state. But I can't find a way to declare the functions—I seem to need a function returning a pointer to a function returning a pointer to a function returning a pointer to a function…, ad infinitum.
A: You can't quite do it directly. One way is to have the function return a generic function pointer (see question 4.13), with some judicious casts to adjust the types as the pointers are passed around:
And then there's a first example using the code shown in the SO question.
As the FAQ answer says, you can't create a function that returns a pointer to its own type of function, so you have to bludgeon the compiler into working.
Line 1: typedef int (*funcptr)();
This has the () at the end because without them, you'd have typedef int (*intptr); or typedef int *intptr; which is not what you want. The empty parentheses are an indeterminate — not empty — list of arguments. It is the way you declare a function pointer — before even trying to compile with my default compilation options, I modified the code to: typedef int (*funcptr)(void);.
A funcptr, therefore, is a pointer to a function that returns an int and (at least for the purposes of this discussion) takes no arguments.
Line 2: typedef funcptr (*ptrfuncptr)();
Don't try this without the intermediate type! This too is a pointer to a function, and the function returns a funcptr — and I used typedef funcptr (*ptrfuncptr)(void); to assert 'and takes no arguments'.
Line 4 & 5: funcptr start(), stop(); etc
These lines declare a set of 5 functions. Again, the argument lists are unspecified — so I'm going to treat them as having (void). These functions return a funcptr. However, their own type is not funcptr. This is the point made in the answer.
Indeed, treated as a name (without the parentheses), the type of start, stop, and state1 through state3 is ptrfuncptr — pointer to a function returning a funcptr.
Line 9: ptrfuncptr state = start;
The variable state is of type ptrfuncptr, and is initialized (without need for casting) to point at the function start. Note that this does not call the function; it merely initializes a variable, just as if you have int i = -37;, it initializes a variable i of type int to the value -37.
Line 12: state = (ptrfuncptr)(*state)();
Time to get the bludgeons out. This line contains a function call and a cast.
The original logic behind function pointers was the 'type mimics use' concept. For example, if you have:
int *p;
then in an expression, *p has the type int. With function pointers, you have:
int (*intfuncptr)();
and in an expression, (*intfuncptr)() represents an int; it is the result of invoking the function pointed at by intptrfunc. In pre-standard C, the (*pointer_to_function)() notation was the only way to use a pointer to function. Standard C allows you to omit the (* and ) around the pointer.
Thus, in modern notation, the line state = (ptrfuncptr)(*state)(); could also be written state = (ptrfuncptr)state();. When I learned C, this wasn't an option, so I still prefer the explicit 'this is invoking a function via a pointer to function' notation. The FAQ does mention this.
So, the line calls the function pointed to by state, and captures the return value in state. But the value returned by the function is a funcptr, not a ptrfuncptr, so we need to bludgeon the compiler into accepting that we know enough of what we're doing to remain silent. So, the (ptrfuncptr) cast does that.
Line 17: return (funcptr)state1;
Since start returns a funcptr, but state1 is a pointer to a function that returns a funcptr, the cast here is, once more, necessary to bludgeon the compiler into accepting the type mismatch. Without parentheses after it, state1 is just the name of the function, not an invocation of the function, and therefore has the type ptrfuncptr — pointer to a function returning a funcptr, not just funcptr which is what start is supposed to return. So, the cast is necessary.
For more mind-blowing function pointers, see:
Understanding typedefs for function pointer in C — examples, hint and tips, please
How typedef works for function pointers
Is it a good idea to typedefpointers? — general answer, no, but there's a strong exception for pointers to functions.
What are the various styles of defining a function returning a function pointer?
…and somewhere there's a question that discusses trivia like state = (ptrfuncptr)(******state)(); (using notation from this Q&A), and the mulitple stars work too…
I'm injecting a DLL into another process and want to call a function that is in that binary based on it's address (0x54315).
How can I actually declare a function, and then set it to this address?
#define FUNC 0x54315
void *myFuncPtr;
int main()
{
myFuncPtr = FUNC; // pretty sure this isn't how
myFuncPtr(); // call it?
}
The existing answers work, but you don't even need a variable for the function pointer. You can just do:
#define myfunc ((void (*)(void))0x54315)
and then call it as myfunc() just like you would an ordinary function. Note that you should change the type in the cast to match the actual argument and return types of the function.
You need to define myFuncPtr as a function pointer, a void* isn't callable.
Best to use a typedef for that:
typedef void (*funptr)(void);
funprt myFuncPtr;
(Assuming your function takes nothing and returns nothing.)
Then you'll get a warning on the assignment - use a type cast to "silence" it, since this is indeed what you need to do.
You're pretty much on your own with this though, if the signature doesn't match, the calling convention is wrong, or the address is wrong, the compiler cannot validate anything and you get to pick up the pieces.
Your code should work once the syntax is corrected to actually be a function pointer. I failed to read it properly for my first version of this answer. Sorry.
As stated by Mat, the proper syntax for a function pointer would be:
void (*myFuncPtr)(void) = (void (*)(void)) FUNC;
This is often simplified by using a typedef since the C function pointer syntax is somewhat convoluted.
Also, you're must be really sure the function to be called is at that same exact address every time your injected DLL runs. I'm not sure how you can be sure of that, though ...
Also, you would need to pay attention to the calling conventions and any arguments the function at FUNC might be expecting, since if you get that wrong you will likely end up with stack corruption.
I came across this in embedded hardware using C.
#define EnterPWDN(clkcon) ( (void (*)(int))0xc0080e0 ) (clkcon)
I have no idea how is this function macro working. I understand clkcon is the function parameter to EnterPWDN, but what is happening after that?
It casts the address 0xc0080e0 to a pointer to function taking an int and returning void, and calls that function, passing clkcon as the parameter.
Spelled out:
typedef void (func_ptr*)(int);
func_ptr func = (func_ptr)0xc0080e0;
func(clkcon);
(If you haven't come across function pointers, you might want to grab a good C introduction and read up on the subject.)
Its a void function pointer that takes an int as a parameter. The function is held at the specific memory address 0xc0080e0.
(void (*)(int))
The above is a function pointer declaration. First comes the void return type. Next comes the fact that its a pointer and finally the int tells you what the parameter to the function is. The memory address is the location the function is stored at and the whole thing is casting that memory address into the correct function pointer type and then calling the function and passing "clkcon" to it.
Excellent answers Goz and sbi, but to put it another way:
At a specific address (0xc0080e0) in memory, possibly in a ROM, there is a function. You call this function with the int clkcon argument.