By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,851 Members | 983 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,851 IT Pros & Developers. It's quick & easy.

Wierd function

P: n/a
mlt
How is it possible from main to supply MyErrorHandler wihtout arguments?

void MyErrorHandler(CGcontext context, CGerror error, void *data) {
char *progname = (char *)data;
fprintf(stderr, "%s: Error: %s\n", progname, cgGetErrorString(error));
}

void main(int argc, char *argv[])
{
....
cgSetErrorHandler(MyErrorHandler, (void *)argv[0]);
....
}
Oct 13 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
mlt wrote:
How is it possible from main to supply MyErrorHandler wihtout arguments?

void MyErrorHandler(CGcontext context, CGerror error, void *data) {
char *progname = (char *)data;
fprintf(stderr, "%s: Error: %s\n", progname, cgGetErrorString(error));
}

void main(int argc, char *argv[])
That should be `int main', and you will be punished for this
departure from the ways of righteousness. Cardinal Fang, poke
him with the soft cushions!
{
...
cgSetErrorHandler(MyErrorHandler, (void *)argv[0]);
This is *not* a call to the MyErrorHandler function. It is
a call to the cgSetErrorHandler function, passing two arguments.
The first argument is a pointer to the MyErrorHandler function,
and the second is a pointer to the program's first command-line
argument (ordinarily the program name), converted from a `char*'
to a `void*'.

There are quite a few pieces missing from the snippet you've
posted, but I'd guess that the scenario goes something like this:
cgSetErrorHandler stores its two arguments somewhere and returns,
probably without doing much of anything else. Later on, if the
CG framework detects an error of some kind, the error-processing
code will retrieve the values that were stored earlier and will
use them to call the pointed-to function -- in this case, to call
MyErrorHandler. The MyErrorHandler function appears to take
three arguments: A CGcontext and a CGerror, which presumably give
information about the error, and a `void*' which is most likely
the other value stashed by cgErrorHandler.

This technique is often referred to as using a "callback,"
meaning that the invoker provides a function pointer to a called
function or suite of functions, which then uses the pointer to
"call back" to the function the invoker provided. The Standard C
library includes a few uses of this technique: the qsort() and
bsearch() functions are often cited as uses of callback, but the
way atexit() "registers" functions to be called during exit()
processing seems a closer match to the situation you've shown.

--
Er*********@sun.com
Oct 13 '08 #2

P: n/a
"mlt" <as**@asd.comwrites:
How is it possible from main to supply MyErrorHandler wihtout arguments?

void MyErrorHandler(CGcontext context, CGerror error, void *data) {
char *progname = (char *)data;
fprintf(stderr, "%s: Error: %s\n", progname, cgGetErrorString(error));
}

void main(int argc, char *argv[])
{
...
cgSetErrorHandler(MyErrorHandler, (void *)argv[0]);
...
}
A function name not followed by a parenthesized argument list isn't a
function call, it's a reference to the name of the function. This
calls the cgSetErrorHandler function, passing the address of the
MyErrorHandler function as an argument.

Presumably cgSetErrorHandler will save this address somewhere so it
can be used later for an indirect call.

Incidentally, main returns int, not void; the correct declaration is:

void main(int argc, char *argv[])

See the comp.lang.c FAQ, <http://www.c-faq.com/>, questions 11.12a,
11.12b, 11.14a, 11.14b, and 11.15.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 13 '08 #3

P: n/a
On 13 Oct 2008 at 19:31, Keith Thompson wrote:
the correct declaration is:

void main(int argc, char *argv[])
There it is, right from the horse's mouth! Worthy of forming someone's
signature...

Oct 13 '08 #4

P: n/a
Keith Thompson <ks***@mib.orgwrites:
[...]
Incidentally, main returns int, not void; the correct declaration is:

void main(int argc, char *argv[])

See the comp.lang.c FAQ, <http://www.c-faq.com/>, questions 11.12a,
11.12b, 11.14a, 11.14b, and 11.15.
Oops, that was a copy-and-paste error; sorry about that.

The correct declaration is:

int main(int argc, char *argv[])

(Or you can use "int main(void)" if you're not going to refer to the
command-line arguments, but that doesn't apply in this case.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 13 '08 #5

P: n/a
mlt wrote:
How is it possible from main to supply MyErrorHandler wihtout arguments?

void MyErrorHandler(CGcontext context, CGerror error, void *data) {
char *progname = (char *)data;
fprintf(stderr, "%s: Error: %s\n", progname, cgGetErrorString(error));
}

void main(int argc, char *argv[])
{
...
cgSetErrorHandler(MyErrorHandler, (void *)argv[0]);
...
}
Note the lack of parentheses after MyErrorHandler, which means it isn't
being called here and thus doesn't need arguments.

In this case, MyErrorHandler decays to a pointer-to-function, and that
pointer is an argument to the cgSetErrorHandler() function call.

Given the names and function signatures involved, this is most likely
setting up a "callback" function where, instead of your code calling the
library, you tell the library how to call yours. The syntax for this
can look pretty complicated, but the idea is simple once you understand
that you can have pointers to functions just like you can have pointers
to objects.

S
Oct 13 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.