Setting a pointer to a function, inside a function
Author |
Message |
Chri #1 / 9
|
Setting a pointer to a function, inside a function
Hi, im having a strange problem (or i dont understand something!)... As part of an initialisation sequence i call a function which registers a number of callbacks. One of the parameters is a callback which the calling function will call when it receives data (hope that makes sense - seems backward i know but it is required in this case). A code example is given bellow: void functionToBeCalled(uint8* data) { Quote: }
void setPtr(void (*callback)(uint8*)) { callback = functionToBeCalled; Quote: }
// calling code is shown bellow. this should set the local function // pointer variable to functiontoBeCalled... void (*temp)(uint8*) = 0; setPtr(temp); // on return temp is still 0?? The code compiles and runs ok, i have stepped into the setPtr function, the value is assigned but when the function returns the calling function temp hasnt been updated with the value. Any clues as to what i am missing? Thanks in advance, Chris
|
Fri, 01 Apr 2005 22:22:25 GMT |
|
|
Richard B #2 / 9
|
Setting a pointer to a function, inside a function
Quote:
> void (*temp)(uint8*) = 0; > setPtr(temp); > // on return temp is still 0?? > The code compiles and runs ok, i have stepped into the setPtr > function, the value is assigned but when the function returns the > calling function temp hasnt been updated with the value.
This has nothing to do with callbacks or with function pointers in particular, and everything with the fact that a function pointer is a pointer, and hence an object, too. If you want to change a pointer within a function, you have to pass a pointer _to_ that pointer, just as to change an int, you pass a pointer _to_ that int; this is true for function pointers as much as for object pointers. Oddly *ahem* enough, this is in the FAQ: <http://www.eskimo.com/~scs/C-faq/q4.8.html>. Richard
|
Fri, 01 Apr 2005 22:46:31 GMT |
|
|
Neil Butterwort #3 / 9
|
Setting a pointer to a function, inside a function
Quote: > Hi, im having a strange problem (or i dont understand something!)... > As part of an initialisation sequence i call a function which > registers a number of callbacks. One of the parameters is a callback > which the calling function will call when it receives data (hope that > makes sense - seems backward i know but it is required in this case). > A code example is given bellow: > void functionToBeCalled(uint8* data) > { > } > void setPtr(void (*callback)(uint8*)) > { > callback = functionToBeCalled; > } > // calling code is shown bellow. this should set the local function > // pointer variable to functiontoBeCalled... > void (*temp)(uint8*) = 0; > setPtr(temp); > // on return temp is still 0?? > The code compiles and runs ok, i have stepped into the setPtr > function, the value is assigned but when the function returns the > calling function temp hasnt been updated with the value. > Any clues as to what i am missing?
Pointers, like all other objects in C++ apart from arrays are passed to functions by value. When you say: void (*temp)(uint8*) = 0; setPtr(temp); a copy of the pointer temp is made and it is that copy that is modified in setPtr(). When setPtr() ends, the copy is discarded. It's exactly as if you said: void f( int x ) { x = 3; Quote: }
Solution? Use a reference. NeilB
|
Fri, 01 Apr 2005 22:55:28 GMT |
|
|
Mark A. Odel #4 / 9
|
Setting a pointer to a function, inside a function
Quote: > Hi, im having a strange problem (or i dont understand something!)... > As part of an initialisation sequence i call a function which > registers a number of callbacks. One of the parameters is a callback > which the calling function will call when it receives data (hope that > makes sense - seems backward i know but it is required in this case). > A code example is given bellow: > void functionToBeCalled(uint8* data) > { > } > void setPtr(void (*callback)(uint8*)) > { > callback = functionToBeCalled; > }
Let's take a simple example to show why this won't work. static int s_masterFoo; void setFoo1(int *pFoo1) { /* We enter setFoo() with pFoo1 pointing to pFoo in main(). ** The next line obliterates that address and sets our ** _local_ parameter pFoo1 to point to the address of ** s_masterFoo. The pFoo pointer is still uninitialized. */ pFoo1 = &s_masterFoo; /* As we return from setFoo() to main(), the value of ** pFoo1 is discarded so this function is quite useless. */ Quote: }
void setFoo2(int **pFoo2) { /* We enter setFoo() with pFoo2 pointing to &pFoo in main(). ** The next line sets pFoo to point to s_masterFoo. */ *pFoo2 = &s_masterFoo; /* As we return from setFoo() to main(), the context of ** pFoo2 is discarded, but pFoo is still pointing to ** s_masterFoo which is much more useful. */ Quote: }
int main(void) { int *pFoo; setFoo1(pFoo); /* Does not change pFoo */ setFoo2(&pFoo); /* Changes pFoo to point to s_masterFoo */ return 0; Quote: }
In the end you want a pointer to a pointer. Enjoy.
|
Fri, 01 Apr 2005 22:53:28 GMT |
|
|
Eric Sosma #5 / 9
|
Setting a pointer to a function, inside a function
Quote:
> [...] > void functionToBeCalled(uint8* data) > { > } > void setPtr(void (*callback)(uint8*)) > { > callback = functionToBeCalled; > } > // calling code is shown bellow. this should set the local function > // pointer variable to functiontoBeCalled... > void (*temp)(uint8*) = 0; > setPtr(temp); > // on return temp is still 0?? > The code compiles and runs ok, i have stepped into the setPtr > function, the value is assigned but when the function returns the > calling function temp hasnt been updated with the value. > Any clues as to what i am missing?
You're going to kick yourself when you realize this is Question 4.8 in the comp.lang.c Frequently Asked Questions (FAQ) list http://www.eskimo.com/~scs/C-faq/top.html --
|
Fri, 01 Apr 2005 23:50:16 GMT |
|
|
Jonas Lindstr? #6 / 9
|
Setting a pointer to a function, inside a function
comp.lang.c: Quote:
>> Hi, im having a strange problem (or i dont understand >> something!)... >> As part of an initialisation sequence i call a function >> which registers a number of callbacks. One of the parameters >> is a callback which the calling function will call when it >> receives data (hope that makes sense - seems backward i know >> but it is required in this case). A code example is given >> bellow:
[snip] Quote: > Solution? Use a reference.
I was a bit startled at first when I read this (Hey! C doesn't have references!), but then I realised that this thread was cross- posted to comp.lang.c and comp.lang.c++. So the answer is of course correct - for C++. Chris - if you don't know whether you are writing C or C++, you are likely to get confused. --
Stockholm, Sweden
|
Sat, 02 Apr 2005 03:06:58 GMT |
|
|
Shagg #7 / 9
|
Setting a pointer to a function, inside a function
Groovy hepcat Chris was jivin' on 14 Oct 2002 07:22:25 -0700 in comp.lang.c. Setting a pointer to a function, inside a function's a cool scene! Dig it! Quote: >Hi, im having a strange problem (or i dont understand something!)...
<To Chris> There's nothing so strange about this. It's an extremely common newbie problem. <To the heavens> Why don't these people ever read the FAQ before asking? Quote: >As part of an initialisation sequence i call a function which >registers a number of callbacks. One of the parameters is a callback >which the calling function will call when it receives data (hope that >makes sense - seems backward i know but it is required in this case). >A code example is given bellow: >void functionToBeCalled(uint8* data) >{ >} >void setPtr(void (*callback)(uint8*)) >{ > callback = functionToBeCalled; >} >// calling code is shown bellow. this should set the local function >// pointer variable to functiontoBeCalled... >void (*temp)(uint8*) = 0; >setPtr(temp); >// on return temp is still 0??
<To Chris again> Read this excerpt from the FAQ: ======================================================================== 4.8: I have a function which accepts, and is supposed to initialize, a pointer: void f(int *ip) { static int dummy = 5; ip = &dummy; } But when I call it like this: int *ip; f(ip); the pointer in the caller remains unchanged. A: Are you sure the function initialized what you thought it did? Remember that arguments in C are passed by value. The called function altered only the passed copy of the pointer. You'll either want to pass the address of the pointer (the function will end up accepting a pointer-to-a-pointer), or have the function return the pointer. See also questions 4.9 and 4.11. ======================================================================== - the comp.lang.c FAQ, http://www.eskimo.com/~scs/C-faq/top.html. To paraphrase Bruce Lee in Enter the Dragon, it's like a finger pointing the way to the function called Moon(). If you assign a value to the finger you will miss all that heavenly glory. Actually, it's more like a finger that may or may not be pointing at some random place in the universe, and you want it to point at the Moon. But the problem is that it's not your finger, but someone else's, and you have to tell them which of their many fingers you want them to use to point at the Moon. How do you do that? What you're trying to do is move your finger to point at the Moon, but that doesn't change any of the other person's fingers. You can tell them to point at the Moon, but they don't know which finger to use. You have to point at the finger you want the person to use while telling them to point at the Moon. (The reading of questions 4.9 and 4.11 as well as all the others is left as an exercise for you to do.) P.S.: why did you cross post this to comp.lang.c and comp.lang.c++? These deal with two completely different animals. Though they may look superficially similar, C and C++ are very different. My answer pertains to the former newsgroup, to which I have restricted it. A different response may be pertinent in the latter one. (Because, for example, C++ has references while C does not.) -- Dig the even newer still, yet more improved, sig! http://alphalink.com.au/~phaywood/ "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker. I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
|
Mon, 04 Apr 2005 10:25:26 GMT |
|
|
Shagg #8 / 9
|
Setting a pointer to a function, inside a function
Groovy hepcat Mark A. Odell was jivin' on 14 Oct 2002 14:53:28 GMT in comp.lang.c. Re: Setting a pointer to a function, inside a function's a cool scene! Dig it! Quote:
>> Hi, im having a strange problem (or i dont understand something!)... >> As part of an initialisation sequence i call a function which >> registers a number of callbacks. One of the parameters is a callback >> which the calling function will call when it receives data (hope that >> makes sense - seems backward i know but it is required in this case). >> A code example is given bellow: >> void functionToBeCalled(uint8* data) >> { >> } >> void setPtr(void (*callback)(uint8*)) >> { >> callback = functionToBeCalled; >> } >Let's take a simple example to show why this won't work. >static int s_masterFoo; >void setFoo1(int *pFoo1) >{ > /* We enter setFoo() with pFoo1 pointing to pFoo in main().
No, we don't. We don't enter setFoo() at all, since there is no such function. However, we enter setFoo1() with pFoo1 pointing to... what? pFoo in main()? No. It is pointing to outer space. It has the same value as pFoo in main(), and that is pointing to outer space. So, therefore, pFoo1 is pointing to outer space. Quote: > ** The next line obliterates that address and sets our
No, it doesn't. How can an address be obliterated? A pointer value can be changed, but an address continues to exist. Suppose I write your address down on a piece of paper. If I erase that and write some other address, does that obliterate your address? No. It changes what is written on the piece of paper, but your address still exists. (If it doesn't, you can't come and live at my place.) Quote: > ** _local_ parameter pFoo1 to point to the address of > ** s_masterFoo. The pFoo pointer is still uninitialized. > */ > pFoo1 = &s_masterFoo; > /* As we return from setFoo() to main(), the value of
How can we return from a function that does not exist? Quote: > ** pFoo1 is discarded so this function is quite useless. > */ >} >void setFoo2(int **pFoo2) >{ > /* We enter setFoo() with pFoo2 pointing to &pFoo in main().
No, we don't. I told you before, we don't enter setFoo() at all, since there's no such thing. We enter setFoo2() with pFoo2 pointing... where? C'mon, you can get it. It's not hard. pFoo2 has the same value as the expression &pFoo in main(), which equals the address of pFoo. So pFoo2 is pointing at...? Quote: > ** The next line sets pFoo to point to s_masterFoo. > */ > *pFoo2 = &s_masterFoo; > /* As we return from setFoo() to main(), the context of
As we return from setFoo(), which still does not exist, we hear the smell of blue; and wonder at the pretty lights, of colours never before witnessed by human eyes, that exist in total darkness. Then, before we know it, we're surrounded by weird and scary monsters, snarling and drooling as they tear and chew on our flesh. It's about this time we realise our acid is bad, and our trip has turned into a severe night terror. Some time later we crash land in a pool of our own sweat, drool and vomit, and have an overwelming need for munchies. We swear we'll never do acid again, but, secretly, we know we will at the first oportunity we get. We're determined to see God if it takes all the non-existent functions in the universe. Quote: > ** pFoo2 is discarded, but pFoo is still pointing to > ** s_masterFoo which is much more useful. > */ >} >int main(void) >{ > int *pFoo; > setFoo1(pFoo); /* Does not change pFoo */ > setFoo2(&pFoo); /* Changes pFoo to point to s_masterFoo */ > return 0; >} >In the end you want a pointer to a pointer. Enjoy.
Indeed. Or a returned pointer. -- Dig the even newer still, yet more improved, sig! http://alphalink.com.au/~phaywood/ "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker. I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
|
Mon, 04 Apr 2005 10:25:27 GMT |
|
|
Mark A. Odel #9 / 9
|
Setting a pointer to a function, inside a function
Quote: > Groovy hepcat Mark A. Odell was jivin' on 14 Oct 2002 14:53:28 GMT in > comp.lang.c. > Re: Setting a pointer to a function, inside a function's a cool scene! > Dig it!
>>> Hi, im having a strange problem (or i dont understand something!)... >>> As part of an initialisation sequence i call a function which >>> registers a number of callbacks. One of the parameters is a callback >>> which the calling function will call when it receives data (hope that >>> makes sense - seems backward i know but it is required in this case). >>> A code example is given bellow: >>> void functionToBeCalled(uint8* data) >>> { >>> } >>> void setPtr(void (*callback)(uint8*)) >>> { >>> callback = functionToBeCalled; >>> } >>Let's take a simple example to show why this won't work. >>static int s_masterFoo; >>void setFoo1(int *pFoo1) >>{ >> /* We enter setFoo() with pFoo1 pointing to pFoo in main(). > No, we don't. We don't enter setFoo() at all, since there is no such > function.
Typo. Quote: > However, we enter setFoo1() with pFoo1 pointing to... what? > pFoo in main()? No. It is pointing to outer space.
Correct. Quote: > It has the same > value as pFoo in main(), and that is pointing to outer space. So, > therefore, pFoo1 is pointing to outer space.
To the same planet as pFoo in main() was my point. Quote: >> ** The next line obliterates that address and sets our > No, it doesn't. How can an address be obliterated?
By overwriting it with a new one, what is this? English class? The unknown address pointed to by pFoo1 is replaced with the address of s_masterFoo. Local speak: "We obliterated whatever pFoo1 pointed to and replaced it with something else." Quote: > A pointer value > can be changed, but an address continues to exist.
No sh*t. Quote: > Suppose I write your address down on a piece of paper. If I erase > that and write some other address, does that obliterate your address? > No. It changes what is written on the piece of paper, but your address > still exists. (If it doesn't, you can't come and live at my place.)
Suppose you deal with linker control files all your life in development of embedded systems like me and realize that addresses are the names we give addressable cells within physical devices and furthermore it is quite clear that these logical names can no more be removed from existence than can the concept of the color blue. You need to move on. Quote: >> ** _local_ parameter pFoo1 to point to the address of >> ** s_masterFoo. The pFoo pointer is still uninitialized. >> */ >> pFoo1 = &s_masterFoo; >> /* As we return from setFoo() to main(), the value of > How can we return from a function that does not exist? >> ** pFoo1 is discarded so this function is quite useless. >> */ >>} >>void setFoo2(int **pFoo2) >>{ >> /* We enter setFoo() with pFoo2 pointing to &pFoo in main(). > No, we don't. I told you before, we don't enter setFoo() at all, > since there's no such thing. We enter setFoo2() with pFoo2 pointing...
This is why we don't comment the obvious in production code, it's too easy to get out of sync. with the code. Quote: > where? C'mon, you can get it. It's not hard. pFoo2 has the same value > as the expression &pFoo in main(), which equals the address of pFoo. > So pFoo2 is pointing at...? >> ** The next line sets pFoo to point to s_masterFoo. >> */ >> *pFoo2 = &s_masterFoo; >> /* As we return from setFoo() to main(), the context of > As we return from setFoo(), which still does not exist, we hear the > smell of blue; and wonder at the pretty lights, of colours never > before witnessed by human eyes, that exist in total darkness. Then, > before we know it, we're surrounded by weird and scary monsters, > snarling and drooling as they tear and chew on our flesh. It's about > this time we realise our acid is bad, and our trip has turned into a > severe night terror. Some time later we crash land in a pool of our > own sweat, drool and vomit, and have an overwelming need for munchies. > We swear we'll never do acid again, but, secretly, we know we will at > the first oportunity we get. We're determined to see God if it takes > all the non-existent functions in the universe.
As an engineer, this is just too far out for me to handle. Thanks for playing.
|
Mon, 04 Apr 2005 21:05:29 GMT |
|
|
|