Re: Function pointer to void function and int function



Giannis Papadopoulos wrote:
Eric Sosman wrote:
[... function pointer type must match type of called function ...]
Yes but all I want is to ignore the returning value.
And I need a function pointer to switch between the 2.

The issue is that the type of the function's value is part of the "signature," and can influence the way the function is called and the way its returned value (if any) is retrieved. For example, some implementations compile

	struct foo func(void) {
	    struct foo f;
	    ...
	    return f;
	}
	...
	struct foo f2 = func();

as if it had been written

	void func(struct foo* _value_ptr) {
	    struct foo f;
	    ...
	    *_value_ptr = f;
	}
	...
	struct foo f2;
	struct foo _returned_struct;
	foo(&_returned_struct);
	f2 = _returned_struct;

to avoid the need to find a "secret place" (stack, register,
whatever) that's suitable for holding a possibly large struct.
If you call such a function through a `(void(*)(void))' pointer,
the compiler will not know it's supposed to generate the hidden
`_value_ptr' argument nor the hidden `_returned_struct' object
it should point to.  Even if you intend to ignore the returned
value, it's obvious such a call is wrong and possibly fatal.

    Now, on many machines it will turn out that the machinery
that calls a function returning `int' and ignores the returned
value is identical to the machinery that calls a `void' function.
This is partly accidental, but also partly intentional.  In pre-
Standard C there was no `void', so the way one wrote what we'd
now describe as a `void' function was to write a function that
(formally speaking) was `int'-valued, even though it would not
actually return a value.  The people who develop C compilers have
considerable incentive to see to it that as much old code as
possible continues to work, so there's an excellent chance that
you'll get away with your abuse of the language.  However, it
is an abuse, and new code should avoid it.  Someday, somebody
will find he can generate more efficient code if he does not
cater to practices that are more than fifteen years out of date,
and then where will you be?  Don't Do That.

Hmm, maybe this would be better?

#include <stdio.h>

void a(void) {
    printf("a called.\n");
}

int b(void) {
    printf("b called.\n");
    return 0x1;
}

static void c(void) {
    b();
}

int main(void) {
    void (*p)(void);

    p = &a;
    p();
    p = &c;
    p();

    return 0;
}

This is fine. In fact, this is an excellent technique for using pointers to call functions that may have widely different argument and result types: You "wrap" each target function in a "helper" function, and see to it that all the helpers have the same type.

--
Eric Sosman
esosman@xxxxxxxxxxxxxxxxxxx
.



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: 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)
  • Re: Whats the meaning of this code
    ... void * work ... Whats the meaning of this line:- ... The meaning...a function called work that accepts a pointer of type ... pointer value is cast to an int value. ...
    (comp.lang.c)