473,804 Members | 3,156 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Function pointer to void function and int function

I have the following code

#include <stdio.h>

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

int b(void) {
printf("b called.\n");

return 0x1;
}

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

p = a;
p();
p = b;
p();

return 0;
}

However, it does issue a warning that I am trying to assign a function
of wrong type. Is there any portable way to say to the compiler "shut
up, I know what I am doing?"

And what is the most common way of declaring and using function
pointers, the above or this?

p = &a;
(*p)();

--
one's freedom stops where others' begin

Giannis Papadopoulos
http://dop.users.uth.gr/
University of Thessaly
Computer & Communications Engineering dept.
Nov 15 '05 #1
5 2172
Giannis Papadopoulos wrote:
I have the following code

#include <stdio.h>

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

int b(void) {
printf("b called.\n");

return 0x1;
}

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

p = a;
p();
p = b;
p();

return 0;
}

However, it does issue a warning that I am trying to assign a function
of wrong type. Is there any portable way to say to the compiler "shut
up, I know what I am doing?"
Yes, there is:

p = (void(*)(void)) b;

However, you'd be telling a lie, because you *don't* know what
you're doing! The subsequent `p();' invokes undefined behavior,
because it uses a pointer of one type to call a function of a
different type. You wouldn't expect

double (*q)(const char*) = (double(*)(cons t char*))strlen;
double d = q("Hello, world!");

to work, would you? Well, the situation's no different in your
code: the pointer does not match the function, the compiler puts
together the wrong kind of function linkage, and anything can
happen.
And what is the most common way of declaring and using function
pointers, the above or this?

p = &a;
(*p)();


It's a matter of taste, I think. I seldom see `p = &a;',
perhaps for the same reason that `char *s = "Hello, world!";' is
more common than `char *s = &"Hello, world!"[0];'. As for the
call, on some pre-Standard compilers this form was required, and
coders who worked in those days may still use it out of habit.
Some may continue to do so just to make it clear that the call
is using a function pointer and not a literal function name; they
feel the code is more "self-documenting" if written this way.
I prefer to write `p();' instead of the more cluttered `(*p)();',
but the preference isn't a strong one.

--
Eric Sosman
es*****@acm-dot-org.invalid

Nov 15 '05 #2
Eric Sosman wrote:
Giannis Papadopoulos wrote:
I have the following code

#include <stdio.h>

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

int b(void) {
printf("b called.\n");

return 0x1;
}

int main(void) {
void (*p)(void);
p = a;
p();
p = b;
p();

return 0;
}

However, it does issue a warning that I am trying to assign a function
of wrong type. Is there any portable way to say to the compiler "shut
up, I know what I am doing"?

Yes, there is:

p = (void(*)(void)) b;

However, you'd be telling a lie, because you *don't* know what
you're doing! The subsequent `p();' invokes undefined behavior,
because it uses a pointer of one type to call a function of a
different type. You wouldn't expect

double (*q)(const char*) = (double(*)(cons t char*))strlen;
double d = q("Hello, world!");

to work, would you? Well, the situation's no different in your
code: the pointer does not match the function, the compiler puts
together the wrong kind of function linkage, and anything can
happen.


Yes but all I want is to ignore the returning value.
And I need a function pointer to switch between the 2.

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;
}

--
one's freedom stops where others' begin

Giannis Papadopoulos
http://dop.users.uth.gr/
University of Thessaly
Computer & Communications Engineering dept.
Nov 15 '05 #3
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_struc t;
foo(&_returned_ struct);
f2 = _returned_struc t;

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_stru ct' 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
es*****@acm-dot-org.invalid
Nov 15 '05 #4
On Mon, 05 Sep 2005 16:37:23 +0300, Giannis Papadopoulos
<ip******@inf.u th.gr> wrote:
Eric Sosman wrote:
Giannis Papadopoulos wrote:
I have the following code

#include <stdio.h>

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

int b(void) {
printf("b called.\n");

return 0x1;
}

int main(void) {
void (*p)(void);
p = a;
p();
p = b;
p();

return 0;
}

However, it does issue a warning that I am trying to assign a function
of wrong type. Is there any portable way to say to the compiler "shut
up, I know what I am doing"?

Yes, there is:

p = (void(*)(void)) b;

However, you'd be telling a lie, because you *don't* know what
you're doing! The subsequent `p();' invokes undefined behavior,
because it uses a pointer of one type to call a function of a
different type. You wouldn't expect

double (*q)(const char*) = (double(*)(cons t char*))strlen;
double d = q("Hello, world!");

to work, would you? Well, the situation's no different in your
code: the pointer does not match the function, the compiler puts
together the wrong kind of function linkage, and anything can
happen.


Yes but all I want is to ignore the returning value.


But you can't. The compiler knows the code for any function called
via p returns nothing. Therefore, it can make assumptions about what
happens when such a function returns. For example, if int returns are
always done in register x, then register x will be unchanged. If
register x is used by code before and after the function call, then it
may not be necessary to reload its value.

In your case, after p=b this will no longer be true. b() changed the
value of register x but the compiler doesn't know it. It might
attempt to reuse the value of register x but now it will get the
residue from b().
And I need a function pointer to switch between the 2.
There are other techniques that don't lead to undefined behavior, such
as a wrapper function, if-then, changing a() so it always returns 0,
etc.

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;
The & is superfluous.
p();
p = &c;
p();

return 0;
}

In the sense that it does not lead to undefined behavior, yes, it is
better.
<<Remove the del for email>>
Nov 15 '05 #5
On Mon, 05 Sep 2005 16:37:23 +0300, Giannis Papadopoulos
<ip******@inf.u th.gr> wrote:
Eric Sosman wrote:
Giannis Papadopoulos wrote:
I have the following code

#include <stdio.h>

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

int b(void) {
printf("b called.\n");

return 0x1;
}

int main(void) {
void (*p)(void);
p = a;
p();
p = b;
p();

return 0;
}

However, it does issue a warning that I am trying to assign a function
of wrong type. Is there any portable way to say to the compiler "shut
up, I know what I am doing"?

Yes, there is:

p = (void(*)(void)) b;

However, you'd be telling a lie, because you *don't* know what
you're doing! The subsequent `p();' invokes undefined behavior,
because it uses a pointer of one type to call a function of a
different type. You wouldn't expect

double (*q)(const char*) = (double(*)(cons t char*))strlen;
double d = q("Hello, world!");

to work, would you? Well, the situation's no different in your
code: the pointer does not match the function, the compiler puts
together the wrong kind of function linkage, and anything can
happen.


Yes but all I want is to ignore the returning value.


But you can't. The compiler knows the code for any function called
via p returns nothing. Therefore, it can make assumptions about what
happens when such a function returns. For example, if int returns are
always done in register x, then register x will be unchanged. If
register x is used by code before and after the function call, then it
may not be necessary to reload its value.

In your case, after p=b this will no longer be true. b() changed the
value of register x but the compiler doesn't know it. It might
attempt to reuse the value of register x but now it will get the
residue from b().
And I need a function pointer to switch between the 2.
There are other techniques that don't lead to undefined behavior, such
as a wrapper function, if-then, changing a() so it always returns 0,
etc.

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;
The & is superfluous.
p();
p = &c;
p();

return 0;
}

In the sense that it does not lead to undefined behavior, yes, it is
better.
<<Remove the del for email>>
Nov 15 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
12119
by: Roy Yao | last post by:
Hello, I need to pass a pointer to a callback function to the lower level modules. But the function is thought to be a virtual member one. How can I get the real address of the virtual member function?
3
425
by: Jan-Henrik Grobe | last post by:
Hallo, I am coming to this newsgroup with a very strange Problem. I have two c++ files A.cpp and B.cpp....In A.cpp I am creating an openGL window and in B.cpp I have stored the callback functions. Important is, that the object A.o has to be created BEFORE B can be compiled. I am sure that sounds confusing but A.cpp is part of a library that is needed for objects I use in B (kind of client-server thing). So I cannot include a B.h in the...
11
2114
by: Edd | last post by:
Hello all, I've made a data structure and an associated set of functions to enable me to store a dynamically-sized array of elements of whatever data type I like. Well that's the idea anyway... My implementation seems to work great for primitive types, structures and unions, but I can't quite get an array of function-pointers working properly. Here's a very reduced version of my code with error checks removed for the sake of brevity.
7
1856
by: Alfonso Morra | last post by:
How can this work ? I have the following declarations in a header: Header ========= typedef void (*VFPTR)(void) ; void FOO_Callback(void*, char*, char*, int, unsigned long, void*,void*); int bar(int *, char *, VFPTR, void *);
41
10067
by: Alexei A. Frounze | last post by:
Seems like, to make sure that a pointer doesn't point to an object/function, NULL (or simply 0) is good enough for both kind of pointers, data pointers and function pointers as per 6.3.2.3: 3 An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed...
17
3265
by: I.M. !Knuth | last post by:
Hi. I'm more-or-less a C newbie. I thought I had pointers under control until I started goofing around with this: ================================================================================ /* A function that returns a pointer-of-arrays to the calling function. */ #include <stdio.h> int *pfunc(void);
3
3660
by: Beta What | last post by:
Hello, I have a question about casting a function pointer. Say I want to make a generic module (say some ADT implementation) that requires a function pointer from the 'actual/other modules' that takes arguments of type (void *) because the ADT must be able to deal with any type of data. In my actual code, I will code the function to take arguments of their real types, then when I pass this pointer through an interface function, I...
26
4888
by: aruna.mysore | last post by:
Hi all, I have a specific problem passing a function pointer array as a parameter to a function. I am trying to use a function which takes a function pointer array as an argument. I am too sure about the syntax of calling the same. #include <stdio.h> void fp1()
20
2251
by: MikeC | last post by:
Folks, I've been playing with C programs for 25 years (not professionally - self-taught), and although I've used function pointers before, I've never got my head around them enough to be able to think my way through what I want to do now. I don't know why - I'm fine with most other aspects of the language, but my brain goes numb when I'm reading about function pointers! I would like to have an array of structures, something like
7
3831
by: ghulands | last post by:
I am having trouble implementing some function pointer stuff in c++ An object can register itself for many events void addEventListener(CFObject *target, CFEventHandler callback, uint8_t event); so I declared a function pointer like typedef void (CFObject::*CFEventHandler)(CFEvent *theEvent);
0
9706
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
10319
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10076
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9144
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7616
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6851
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4297
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3816
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.