Re: typedef function with void parameters



William Xu wrote:
Chris Dollin <chris.dollin@xxxxxx> writes:

So, which do you want -- a function taking a `void*` or a function taking a `char*`? They're not compatible types. Pick one.

Oh, i thought that most pointer types could be converted/stored into
void pointer.

Yes, they can.

I'm trying to wrap different function pointers into FUNC,
like,

,----
| int foo(char *p){}
| int bar(int *p){}
| | typedef int (*FUNC)(void *);
| | FUNC f1 = foo, f2 = bar;
`----

So, this is not allowed?

No, it is not.

Here's why: You can convert a `void*' to or from any other
data pointer type, but you need to know what the other type is
in order to choose the proper conversion. Calling foo() or bar()
with a `void*' argument is all right, because the compiler knows
that it must convert `void*' to `char*' for foo() or convert
`void*' to `int*' for bar(). But when calling f1() -- more
precisely, when calling a function that f1 can point to --
you have told the compiler that no conversion is necessary:
an f1-addressable function takes a `void*' argument, so there
is no need to convert the `void*' that you supply. If f1
points (invalidly) at foo() or bar(), the compiler doesn't
know that it should perform a conversion.

On many machines these "conversions" are just bit-for-bit
copies of the pointers' values, but C does not require such a
simple addressing scheme and is able to run on machines whose
addressing is more intricate. So from the point of view of the
C language, you must keep the compiler properly informed about
the types of things.

Weak analogy: You know how to convert day-to-day natural
numbers to and from Roman numerals, and to and from English
utterances:

1234 <-> "MCCXXXIV"
1234 <-> "one thousand two hundred thirty-four"

Let's imagine that your bag of tricks includes C functions
to do these conversions, so you can think of them as "built-
in" like the conversions between `void*' and `double*'.

Now suppose you're writing a program that involves a few
more functions, each taking an argument representing a number
as a string. One of them wants a Roman representation, and
the other wants and English string:

void needsRoman(const char *roman);
void needsEnglish(const char *english);

When you want to call one of these with an argument that
is actually an integer, you need to do the proper conversion:

int x = 42;
needsRoman( intToRoman(x) );
needsEnglish( intToEnglish(x) );

What you have tried to do (the analogy approaches its
tortured conclusion; the air is thick with anticipation and
ennui) is to invent a construct that can pass `x' to either
needsRoman() or needsEnglish() without knowing which string
representation of `x' is appropriate. Can't be done: You
need to know what the called function expects to receive
before you can know how to meet its expectations.

--
Eric Sosman
esosman@xxxxxxxxxxxxxxxxxxxx
.



Relevant Pages

  • Re: confusion: casting function pointers
    ... pointer from the 'actual/other modules' that takes arguments of type ... list to types of void *). ... int main{ ... without a prototype, a number of special "promotion" rules take ...
    (comp.lang.c)
  • Re: invalid pointer adress
    ... >> pointer causes the program to exit with a core dump. ... struct s2{void *p;}; ... int leseExterneHinweise_masch_storno ... typedef struct s_AusdatFeldbeschreibung ...
    (comp.lang.c)
  • Should io(read|write)(8|16|32)_rep take (const|) volatile u(8|16|32) __iomem *addr?
    ... the destination pointer on user-space ... @src: ... const void *data, int bytelen); ...
    (Linux-Kernel)
  • Re: Ada Pointer Size Problem
    ... >> int. ... > pointer to an int. ... And you can't assign C pointer to integer without conversion; ... need not provide them if it doesn't have a suitable integer type. ...
    (comp.lang.ada)
  • Re: function pointer help!
    ... //the return void and input prameters are defined in the manual... ... void MyProjectView::CallHandler(int,unsigned int, unsigned int, void*) ... You are attempting to use a C++ member function as the callback, but the callback is defined in terms or C, not C++. ... The underlying problem is that C++ functions receive a hidden parameter, the 'this' pointer, so their signature is incompatible with C definitions. ...
    (microsoft.public.vc.mfc)