473,405 Members | 2,445 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

call a function via a function pointer of different type

Hi all

Can one reliably call a function via a function pointer of different type
as below?

struct some_struct {
int some_int;
};

int some_function( struct some_struct *struct_ptr ){
return struct_ptr-some_int;
}

int main( void ){
struct some_struct a_struct= { 42 };
int (*function_pointer)(void*)= & some_function;

return (*function_pointer)( & a_struct );
}

Thanks,
viza
Oct 26 '08 #1
5 1791
viza <to******@gm-il.com.obviouschange.invalidwrites:
Can one reliably call a function via a function pointer of different type
Yes.
as below?
No! You can do it but not like this.
struct some_struct {
int some_int;
};

int some_function( struct some_struct *struct_ptr ){
return struct_ptr-some_int;
}

int main( void ){
struct some_struct a_struct= { 42 };
int (*function_pointer)(void*)= & some_function;
This initialisation requires a diagnostic but it is perfectly OK if
you supply a cast (and I prefer to have no & operator):

int (*function_pointer)(void*)= (int (*)(void *))some_function;
return (*function_pointer)( & a_struct );
and at this point you must convert the pointer to the type of the
function you are actually calling.

return ((int(*)(struct some_struct *))function_pointer)(&a_struct);

and, again, I prefer to omit the * (it turns the pointer into a
function which is converted back to pointer for the call -- at least
in modern C).
}
--
Ben.
Oct 26 '08 #2
Ben Bacarisse wrote:
>
This initialisation requires a diagnostic but it is perfectly OK if
you supply a cast (and I prefer to have no & operator):

int (*function_pointer)(void*)= (int (*)(void *))some_function;
In addition to what Ben said, it's useful to have typedef's for function
pointers. For example:
typedef int (*my_func_t)(void*);

....

my_func_t function_pointer;

....

function_pointer = (my_func_t) some_function;
and when calling:

function_pointer (&arg);
--
Tor <echo bw****@wvtqvm.vw | tr i-za-h a-z>
Oct 26 '08 #3
viza <tom.v...@gm-il.com.obviouschange.invalidwrote:
Hi all

Can one reliably call a function via a function pointer
of different type as below?
Depends on whether you think undefined behaviour is
reliable or not.
struct some_struct {
* int some_int;
};

int some_function( struct some_struct *struct_ptr ){
* return struct_ptr-some_int;
}

int main( void ){
* struct some_struct a_struct= { 42 };
* int (*function_pointer)(void*)= & some_function;
This violates a contraint.
* return (*function_pointer)( & a_struct );
}
Since some_function isn't variadic, and since struct
pointers aren't subject to promotion, you can portably
do...

int (*function_pointer)() = some_function;
return function_pointer( & a_struct );

--
Peter
Oct 27 '08 #4
Ben Bacarisse <ben.use...@bsb.me.ukwrote:
viza <tom.v...@gm-il.com.obviouschange.invalidwrites:
Can one reliably call a function via a function
pointer of different type

Yes.
as below?

No! *You can do it but not like this.
struct some_struct {
* int some_int;
};

int some_function( struct some_struct *struct_ptr ){
* return struct_ptr-some_int;
}

int main( void ){
* struct some_struct a_struct= { 42 };
* int (*function_pointer)(void*)= & some_function;

This initialisation requires a diagnostic but it is
perfectly OK if you supply a cast (and I prefer to
have no & operator):
int (*function_pointer)(void*)= (int (*)(void *))some_function;

* return (*function_pointer)( & a_struct );
Since some_function is not variadic, better is...

int (*function_pointer)() = some_function;
and at this point you must convert the pointer to the
type of the function you are actually calling.

* return ((int(*)(struct some_struct *))function_pointer)
(&a_struct);
With the non-prototype declaration, it's just...

return function_pointer(&a_struct);

--
Peter
Oct 28 '08 #5
Peter Nilsson <ai***@acay.com.auwrites:
Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>viza <tom.v...@gm-il.com.obviouschange.invalidwrites:
Can one reliably call a function via a function
pointer of different type

Yes.
as below?

No! Â*You can do it but not like this.
struct some_struct {
Â* int some_int;
};

int some_function( struct some_struct *struct_ptr ){
Â* return struct_ptr-some_int;
}

int main( void ){
Â* struct some_struct a_struct= { 42 };
Â* int (*function_pointer)(void*)= & some_function;

This initialisation requires a diagnostic but it is
perfectly OK if you supply a cast (and I prefer to
have no & operator):
int (*function_pointer)(void*)= (int (*)(void *))some_function;

Â* return (*function_pointer)( & a_struct );

Since some_function is not variadic, better is...

int (*function_pointer)() = some_function;
Yes, that's neater (and I had forgotten you could still do this in
"modern" C).

I was also pleasantly surprised to find that the compiler is obliged
to diagnose the situation where the default argument promotions could
result in a problem at call time; since in such cases the types are no
longer compatible. This is (I flatter myself) a subtle point that had
passed me by.

This means that it is not just that some_function is not variadic that
makes the initialisation valid. As you mentioned in another post, it
is the fact that the declared arguments to some_function are not
altered by the default argument promotions.

For those as slow on the uptake as myself, I believe that if
some_function is declared:

int some_function(float);

the compiler must diagnose a constraint violation, but if it were
declared

int some_function(double);

the initialisation is from a compatible type. This makes your form
more type-safe (within the limits that C permits) than my version with
the explicit casts. There is no way that C can properly type-check
the final call (given that we have now lost the original function
type) but at least it can check for a subtle incompatibility that
could otherwise slip by.

Thank you for pointing this out.

<snip>
--
Ben.
Oct 28 '08 #6

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

Similar topics

58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
2
by: joe | last post by:
hi, after reading some articles and faq, i want to clarify myself what's correct(conform to standard) and what's not? or what should be correct but it isn't simply because compilers don't...
26
by: Adam Warner | last post by:
Hello all, I'm very new to C but I have a number of years of Common Lisp programming experience. I'm trying to figure out ways of translating higher order concepts such as closures into C. The...
46
by: TTroy | last post by:
Hi, I'm just wondering why people/books/experts say "the function returns a pointer to.." or "we have to send scanf a pointer to.." instead of "the function returns the address of.." or "we have...
16
by: Abhishek | last post by:
why do I see that in most C programs, pointers in functions are accepted as: int func(int i,(void *)p) where p is a pointer or an address which is passed from the place where it is called. what...
17
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: ...
57
by: Robert Seacord | last post by:
i am trying to print the address of a function without getting a compiler warning (i am compiling with gcc with alot of flags). if i try this: printf("%p", f); i get: warning: format %p...
11
by: Felix Kater | last post by:
Hi, I can compile and run this code (see below) which twice calls the function f, first with too less, second with too much arguments. But is it legal and free of memory leaks and other...
12
by: Rahul | last post by:
Hi Everyone, I have the following code and i'm able to invoke the destructor explicitly but not the constructor. and i get a compile time error when i invoke the constructor, why is this so? ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...
0
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,...

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.