473,385 Members | 1,766 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,385 software developers and data experts.

typecasting of function pointers

Hi,
is it possible to typecast a function pointer to two different
prototypes.
eg.,
typedef void (functptr1 *) (int , int);
typedef void (functptr2 *) (int);
functptr1 fptr;
fptr = somefunction_name;
fptr(10,20);
fptr = (functptr2)someotherfunction_name;
(functptr2) fptr(10);

I tried the above it did'nt work. If this is wrong please let me know
how it could be done in the right way, also if it is compiler specific,
which compiler(s) permit this.

Mar 20 '06 #1
12 8335
sr*************@gmail.com schrieb:
Hi,
is it possible to typecast a function pointer to two different
prototypes.
eg.,
typedef void (functptr1 *) (int , int);
typedef void (functptr2 *) (int);
functptr1 fptr;
fptr = somefunction_name;
fptr(10,20);
fptr = (functptr2)someotherfunction_name;
(functptr2) fptr(10);

I tried the above it did'nt work. If this is wrong please let me know
how it could be done in the right way, also if it is compiler specific,
which compiler(s) permit this.


Please, state exactly what "didn't work" means in future.
Have a look at
<http://www.catb.org/~esr/faqs/smart-questions.html>
And provide the _actual_ code.
The above cannot compile.

So, for the language facilities:
1. Function pointers cannot be converted implicitly (i.e.
without cast). They cannot be explicitly (i.e. via cast)
to another function pointer type in a portable, standard
C way.
This means: Whenever you cast one function pointer type
to another, your program becomes inherently non-portable
and may even break when you use another version of the
same compiler.
2. If you have the same return type, you have good chances
that it will work nonetheless; the right way to do the above
is
void foo(int qux, int quux);
void bar(int baz);

fptr = foo;
fptr(10,20);
fptr = (functptr1) bar;
((functptr2)fptr)(10);
with the typedefs and declarations in place.
However, you can run into deep trouble if calling the wrong
type of function with the wrong number of arguments, so this
is a bad idea at best. If you need different pointer types,
consider using a union of function pointers and some kind of
type marker.
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.
3. On many implementations, even casts between function
pointer types for different return types may work.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 20 '06 #2
Michael Mair wrote:
sr*************@gmail.com schrieb:
Hi,
is it possible to typecast a function pointer to two different
prototypes.
eg.,
typedef void (functptr1 *) (int , int);
typedef void (functptr2 *) (int);
functptr1 fptr;
fptr = somefunction_name;
fptr(10,20);
fptr = (functptr2)someotherfunction_name;
(functptr2) fptr(10);

I tried the above it did'nt work. If this is wrong please let me know
how it could be done in the right way, also if it is compiler specific,
which compiler(s) permit this.
Please, state exactly what "didn't work" means in future.
Have a look at
<http://www.catb.org/~esr/faqs/smart-questions.html>
And provide the _actual_ code.
The above cannot compile.

So, for the language facilities:
1. Function pointers cannot be converted implicitly (i.e.
without cast). They cannot be explicitly (i.e. via cast)
to another function pointer type in a portable, standard
C way.
This means: Whenever you cast one function pointer type
to another, your program becomes inherently non-portable
and may even break when you use another version of the
same compiler.


Not completely true. It is perfectly legal to cast from one function
type to another, it's just that you have to cast it back again before
calling it. There are even times when this is useful, although not very
often.
2. If you have the same return type, you have good chances
that it will work nonetheless; the right way to do the above
is
void foo(int qux, int quux);
void bar(int baz);

fptr = foo;
fptr(10,20);
fptr = (functptr1) bar;
((functptr2)fptr)(10);
with the typedefs and declarations in place.
However, you can run into deep trouble if calling the wrong
type of function with the wrong number of arguments, so this
is a bad idea at best. If you need different pointer types,
consider using a union of function pointers and some kind of
type marker.
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.
I would strongly advise against doing this even if it appears to work.
If you do not always use all the parameters then there are two simple
ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for unused
parameters.
2) Write a function that takes a variable number of arguments using the
mechanism C provides for doing this.
3. On many implementations, even casts between function
pointer types for different return types may work.


However, even if it works you should still not do it.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 20 '06 #3
Flash Gordon schrieb:
Michael Mair wrote:
sr*************@gmail.com schrieb:
Hi,
is it possible to typecast a function pointer to two different
prototypes.
eg.,
typedef void (functptr1 *) (int , int);
typedef void (functptr2 *) (int);
functptr1 fptr;
fptr = somefunction_name;
fptr(10,20);
fptr = (functptr2)someotherfunction_name;
(functptr2) fptr(10);

I tried the above it did'nt work. If this is wrong please let me know
how it could be done in the right way, also if it is compiler specific,
which compiler(s) permit this.


Please, state exactly what "didn't work" means in future.
Have a look at
<http://www.catb.org/~esr/faqs/smart-questions.html>
And provide the _actual_ code.
The above cannot compile.

So, for the language facilities:
1. Function pointers cannot be converted implicitly (i.e.
without cast). They cannot be explicitly (i.e. via cast)
to another function pointer type in a portable, standard
C way.
This means: Whenever you cast one function pointer type
to another, your program becomes inherently non-portable
and may even break when you use another version of the
same compiler.


Not completely true. It is perfectly legal to cast from one function
type to another, it's just that you have to cast it back again before
calling it. There are even times when this is useful, although not very
often.


Thanks for pointing that out.
For the record: C99, 6.3.2.3#8

2. If you have the same return type, you have good chances
that it will work nonetheless; the right way to do the above
is
void foo(int qux, int quux);
void bar(int baz);

fptr = foo;
fptr(10,20);
fptr = (functptr1) bar;
((functptr2)fptr)(10);
with the typedefs and declarations in place.
However, you can run into deep trouble if calling the wrong
type of function with the wrong number of arguments, so this
is a bad idea at best. If you need different pointer types,
consider using a union of function pointers and some kind of
type marker.
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.


I would strongly advise against doing this even if it appears to work.
If you do not always use all the parameters then there are two simple
ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for unused
parameters.
2) Write a function that takes a variable number of arguments using the
mechanism C provides for doing this.


Note: The former may not the natural thing to do; sometimes the
union-based approach is more helpful. The latter, especially
with key/value pairs, does not suffer from that but may make for
troublesome parameter combination checking.
3. On many implementations, even casts between function
pointer types for different return types may work.


However, even if it works you should still not do it.


Indeed :-)
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 20 '06 #4
Flash Gordon wrote:
Michael Mair wrote:
.... snip ...
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.


I would strongly advise against doing this even if it appears to
work. If you do not always use all the parameters then there are
two simple ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for
unused parameters.
2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.


I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 21 '06 #5
CBFalconer <cb********@yahoo.com> writes:
Flash Gordon wrote:
2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.


I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.


If you use a compiler that can check variadic function arguments,
then you gain some protection. For example, GCC can check
printf()-style variadic function arguments; newer versions can
also check that an argument list is terminated by a null pointer.
You don't even have to *always* compile with GCC to get some help
from this feature; as long as you sometimes compile with GCC, it
will point out (most of) your mistakes.
--
Bite me! said C.
Mar 21 '06 #6
Michael Mair wrote:
Flash Gordon schrieb:
Michael Mair wrote:
<snip stuff agreed>
2. If you have the same return type, you have good chances
that it will work nonetheless; the right way to do the above
is
void foo(int qux, int quux);
void bar(int baz);

fptr = foo;
fptr(10,20);
fptr = (functptr1) bar;
((functptr2)fptr)(10);
with the typedefs and declarations in place.
However, you can run into deep trouble if calling the wrong
type of function with the wrong number of arguments, so this
is a bad idea at best. If you need different pointer types,
consider using a union of function pointers and some kind of
type marker.
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.


I would strongly advise against doing this even if it appears to work.
If you do not always use all the parameters then there are two simple
ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for unused
parameters.
2) Write a function that takes a variable number of arguments using the
mechanism C provides for doing this.


Note: The former may not the natural thing to do; sometimes the
union-based approach is more helpful. The latter, especially
with key/value pairs, does not suffer from that but may make for
troublesome parameter combination checking.


I agree there are many other approaches. I was just pointing out a
couple of the simplest to implement which don't rely on doing odd stuff
with function pointers, starting with the very simplest.

<snip more stuff agreed>
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 21 '06 #7
Ben Pfaff wrote:
CBFalconer <cb********@yahoo.com> writes:
Flash Gordon wrote:

2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.


I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.


If you use a compiler that can check variadic function arguments,
then you gain some protection. For example, GCC can check
printf()-style variadic function arguments; newer versions can
also check that an argument list is terminated by a null pointer.
You don't even have to *always* compile with GCC to get some help
from this feature; as long as you sometimes compile with GCC, it
will point out (most of) your mistakes.


That's with a constant format string, and for functions that are
defined in the standard. None of which applies to Flashs suggestion
2.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Mar 21 '06 #8
CBFalconer <cb********@yahoo.com> writes:
Ben Pfaff wrote:
For example, GCC can check
printf()-style variadic function arguments; newer versions can
also check that an argument list is terminated by a null pointer.
You don't even have to *always* compile with GCC to get some help
from this feature; as long as you sometimes compile with GCC, it
will point out (most of) your mistakes.
That's with a constant format string, and for functions that are
defined in the standard.


You are wrong about the latter: you can apply these to any
function to you like, using a GCC extension. And, as I said, you
get most of the benefit even if you don't always use GCC.
None of which applies to Flashs suggestion 2.


The null sentinel check might work, or it might not.
--
"I don't have C&V for that handy, but I've got Dan Pop."
--E. Gibbons
Mar 21 '06 #9
On 2006-03-21, CBFalconer <cb********@yahoo.com> wrote:
Ben Pfaff wrote:
CBFalconer <cb********@yahoo.com> writes:
Flash Gordon wrote:

2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.

I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.


If you use a compiler that can check variadic function arguments,
then you gain some protection. For example, GCC can check
printf()-style variadic function arguments; newer versions can
also check that an argument list is terminated by a null pointer.
You don't even have to *always* compile with GCC to get some help
from this feature; as long as you sometimes compile with GCC, it
will point out (most of) your mistakes.


That's with a constant format string, and for functions that are
defined in the standard. None of which applies to Flashs suggestion
2.


Or, via __attribute__'s, for a format string returned by a function
guaranteed to return a format string equivalent to its argument, and for
any function which accepts printf-like or scanf-like format strings.
Mar 21 '06 #10
CBFalconer schrieb:
Flash Gordon wrote:
Michael Mair wrote:


... snip ...
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.


I would strongly advise against doing this even if it appears to
work. If you do not always use all the parameters then there are
two simple ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for
unused parameters.
2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.


I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.


True; sometimes, this something is so inconvenient that people
have more trouble getting that right or find it too tedious --
especially on extension.
Imagine a function which took a structure until V1.3 -- and then
the facilities have been dramatically extended for V2.0.
Now, initializing 20 of 25 struct members to default for the five
members that matter for the respective application can be very
ugly. The "tag list" concept, i.e. passing key-value pairs was
easier on the eye and made for easier checking than the extended
structure.
As there was no clear distinction between often used and seldom
used members (depending on the users), passing several structures
was quite out of the question, too.
If the whole thing had been designed with the extended feature
set in mind, then there would have been better ways than the
variadic function.
As mentioned in my reply to Flash Gordon: The true pain then
happens internally, if there are no longer consistent default
values and the passed key-value pairs have to be checked for
consistency.

This is a corner case which I have seen at least once; in general,
I agree with the notion to restrict the use of variadic functions
to the ones that come with the standard library (and not all of
them).
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 21 '06 #11
Hi,
thanks for all the information

Mar 21 '06 #12
CBFalconer wrote:
Flash Gordon wrote:
Michael Mair wrote:

... snip ...
Note: If your parameter list have many parameters (say >5),
then the chance increases that it will not work.

I would strongly advise against doing this even if it appears to
work. If you do not always use all the parameters then there are
two simple ways to deal with it:
1) Pass suitable 0 values (or some other place marker) for
unused parameters.
2) Write a function that takes a variable number of arguments
using the mechanism C provides for doing this.


I advise against 2). Variadic functions do not provide proper
parameter checking, and are the source of many mistakes. They may
be convenient, but can always be replaced by something.


I'm no fan of variadic functions either, but they are still better than
casting a function pointer to a type that takes fewer arguments as shown
in the argument that started this thread.

My personal preference is for keeping the number of arguments small and
using suggestion 1, which is why it was my first suggestion.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 21 '06 #13

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

Similar topics

11
by: Vinod Patel | last post by:
I have a piece of code : - void *data; ...... /* data initialized */ ...... struct known_struct *var = (struct known_struct*) data; /*typecasting*/ How is this different from simple...
13
by: brian | last post by:
Quick question: if I have a structure: struct foo { unsigned char *packet; unsigned char *ip_src; };
3
by: bnoordhuis | last post by:
Consider this: int foo(int *a, int *b); int (*bar)(void *, void *) = (void *)foo; How legal - or illegal - is the typecast and are there real-world situations where such code will cause...
3
by: jdm | last post by:
In the sample code for the SortedList class, I see the use of a string typecasting macro consisting of a single letter "S". i.e.: Sortedlist->Add(S"Keyval one", S"Item one"); Now I 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...
5
by: WittyGuy | last post by:
How to typecast a "function pointer" to "const void*" type in C++ way? int MyFunction (double money); // Function prototype const void* arg = (const void*)MyFunction; // type casting...
12
by: bwaichu | last post by:
What is the best way to handle this warning: warning: cast from pointer to integer of different size I am casting in and out of a function that requires a pointer type. I am casting an...
12
by: chadsspameateremail | last post by:
What I am trying to do is implement polymorphism in C. Why? This is to build a library which will be a C library and callable from C. However, I want to have polymorphic functions which are...
3
by: sritejv | last post by:
Hello everyone, I am having a problem with typecasting void pointers.I have read the pointer basics but still cant understand why the following test code doesnt work. void *xyz; struct abcd...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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,...

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.