Function Pointers

A

Army1987

Ben said:
The cast is really not helping here. I'd loose it.
So I would, but it silences [sp]lint. I've seen code with

#define V (void)

static void help()
{
V printf("ent -- Calculate entropy of file. Call");
V printf("\n with ent [options] [input-file]");
/* etc... */
V printf("\n %s\n", UPDATE);
}

*cough*
Static checkers are tools, not ends... Or are they?
(That macro manages to be even uglier than the "strange" placement of \n's,
and I've seen much more beautiful macros in IOCCC entries...)
I'll note, in passing, that I don't usually put a return at the end of
void function. I wonder if other people do?

I do in the same circumstances as the ones when I put a continue at the
end of a loop. Namely, when there is no other statement in the block
before it.
 
B

Ben Bacarisse

Richard Heathfield said:
(e-mail address removed) said:


Others have shown you how to typedef a function pointer type. My own take
is that it's better not to do this, because I don't like hiding pointers
in typedefs.

Ditto. In fact I posted such an example in my reply to the OP! I was
not going to bother saying this except that I find I have two points to
add:
So I would typedef the function type itself:

typedef int myfunctiontype(int, char **);

and then I'd define a pointer to it using a good old out-in-the-open *,
like this:

myfunctiontype *entrypoint = main;

(It's true that myfunctiontype foo; is an error because you can't create
objects of function type, but the answer to that is easy: Don't Do
That.)

You can, however, *declare* functions using it. I have done that once or
twice in code that looked a bit like this:

typedef int op_type(int, int);

extern op_type op_add, op_sub, op_mul, op_div;

op_type *op_table[] = { op_add, op_sub, op_mul, op_div };

It does not buy you much, but it is slightly neater than some alternatives.
I accept that this way may not be everybody's slice of apple pie. Style is
often a matter of taste.

I also prefer to see the "pointerlyness" of pointers, but when it is
hidden I think it matters least with function pointers, simply because
the use makes the type so clear. As soon as you see

op_table[0](a, b);

you know what is going on. There are operations on data pointers that
don't make it obvious that they are pointers (like addition) but you
can so little with a function pointer that I worry less when I see a
"hidden pointer" typedef.
 
B

Ben Bacarisse

Army1987 said:
Ben Bacarisse wrote:

I do in the same circumstances as the ones when I put a continue at the
end of a loop. Namely, when there is no other statement in the block
before it.

And so do I. The odd but is that I did not even know I did until you
pointed this out! It just looks better.
 
R

Richard Heathfield

Ben Bacarisse said:
Ditto. In fact I posted such an example in my reply to the OP!

Oops, so you did. I even read it, actually - but I have a memory like a...
like a... sort of bowl-shaped, you use it to sift, um, well, cooky stuff,
goes in bread...

myfunctiontype *entrypoint = main;

(It's true that myfunctiontype foo; is an error because you can't create
objects of function type, but the answer to that is easy: Don't Do
That.)

You can, however, *declare* functions using it. I have done that once or
twice in code that looked a bit like this:

typedef int op_type(int, int);

extern op_type op_add, op_sub, op_mul, op_div;

op_type *op_table[] = { op_add, op_sub, op_mul, op_div };

It does not buy you much, but it is slightly neater than some
alternatives.

Yes, it's also quite handy for "window procedures" in Win32 API
programming. I don't often write Win32 programs, but when I do, I use a
*lot* of functions that have the same signature as a so-called wndproc -
at least one per handled message.
I also prefer to see the "pointerlyness" of pointers, but when it is
hidden I think it matters least with function pointers, simply because
the use makes the type so clear.

To some extent I agree, but I do find it much easier to keep going with a
good habit if I don't allow myself unnecessary exceptions. :)

<snip>
 
C

CBFalconer

Richard said:
Ben Bacarisse said:
.... snip ...

Oops, so you did. I even read it, actually - but I have a memory
like a... like a... sort of bowl-shaped, you use it to sift, um,
well, cooky stuff, goes in bread...

You are obviously aging. The last few years I keep having problems
remembering the appropriate word (or equivalent). I know I know
it, I just can't dredge it up at the moment. It will probably come
to me later when it is of little use. I am convinced it is an age
effect, but not especially serious, since I can always refer to the
whoozit, or the watch-a-ma-call-it, etc. and anybody of any
intelligence will know exactly what I mean.
 
D

David Thompson

For function pointers, you can convert a value from any
pointer-to-function type to any other pointer-to-function type and
back again, and you're guaranteed to get back the original value. (In
that sense, all pointer-to-function types act like void*). But *none*
of these conversions can be done implicitly; they all require a cast
(unless you're converting from a type to the same type).
One other exception: use 'oldstyle' (unprototyped) pointer types,
as long as you match the return type _only_.

You can convert pointer to func of any (or no) args returning int
int (*) (any specific list or void)
to or from pointer to func of unspecified args returning int
int (*) ( /* empty parens */ )
without a cast.

Whether doing this is a good idea is a separate and dissimilar round
cooking vessel of piscine individuals.
But if you try to use a converted function pointer without converting
it back to its original type, the behavior is undefined. Don't do
that.
Or converting it to the unspecified/oldstyle form with the correct
return type, IFF the actual arguments after default promotions match
the nonvararg definition. But that's harder to get, and keep, right,
without the compiler assistance that correct prototypes give you.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,198
Latest member
JaimieWan8

Latest Threads

Top