473,662 Members | 2,622 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

typedef Used to Cast Function Pointers

Is is possible to use typedefs to cast function pointers? I think I
saw this in the WINGs src; grep for '(hashFunc)'. So far, trying to
use a typedef to cast function pointers so that a return value of
float is changed to float seems not to work; I belive it was like
this:

typedef int (*foo) (int);

function_ptr_ba r = (foo)function_t hat_returns_flo at;
Nov 13 '05 #1
10 10023
Barbrawl McBribe wrote:
Is is possible to use typedefs to cast function pointers?
Only a cast expression can be used to cast.
I think I
saw this in the WINGs src; grep for '(hashFunc)'. So far, trying to
use a typedef to cast function pointers so that a return value of
float is changed to float seems not to work; I belive it was like
this:

typedef int (*foo) (int);
This declares foo as an alias for type "pointer to function taking 1
argument of type int and returning int".

function_ptr_ba r = (foo)function_t hat_returns_flo at;


This uses a cast expression to convert from one type to another. I don't
believe you can safely call the function through the resulting pointer
unless it is first cast back to the correct type.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #2
fi*******@theli nuxlink.net (Barbrawl McBribe) writes:
Is is possible to use typedefs to cast function pointers? I think I
saw this in the WINGs src; grep for '(hashFunc)'. So far, trying to
use a typedef to cast function pointers so that a return value of
float is changed to float seems not to work; I belive it was like
this:

typedef int (*foo) (int);

function_ptr_ba r = (foo)function_t hat_returns_flo at;


I presume you mean "so that a return value of float is changed to
int".

Why would you want to do this? You can probably make it work, but
it's extremely unsafe and non-portable. Basically, you're trying to
lie to the compiler. At best, you'll call function_that_r eturns_float()
and treat its result as an int (not a numeric conversion, but a
reinterpretatio n of the bits). At worst, the calling conventions will
differ, and arbitrarily bad things will happen, from getting
meaningless garbage to crashing your program.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 13 '05 #3


Keith Thompson wrote:
fi*******@theli nuxlink.net (Barbrawl McBribe) writes:
Is is possible to use typedefs to cast function pointers? I think I
saw this in the WINGs src; grep for '(hashFunc)'. So far, trying to
use a typedef to cast function pointers so that a return value of
float is changed to float seems not to work; I belive it was like
this:

typedef int (*foo) (int);

function_ptr_ bar = (foo)function_t hat_returns_flo at;

I presume you mean "so that a return value of float is changed to
int".

Why would you want to do this? You can probably make it work, but
it's extremely unsafe and non-portable. Basically, you're trying to
lie to the compiler. At best, you'll call function_that_r eturns_float()
and treat its result as an int (not a numeric conversion, but a
reinterpretatio n of the bits). At worst, the calling conventions will
differ, and arbitrarily bad things will happen, from getting
meaningless garbage to crashing your program.


The Standard explicitly calls it Undefined Behavior.

From 6.3.2.3.8
"A pointer to a function of one type may be converted to
a pointer to a function of another type and back again;
the result shall compare equal to the original pointer.
If a converted pointer is used to call a function whose
type is not compatible with the pointed-to type, the
behavior is undefined."
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #4
Al Bowers wrote:

The Standard explicitly calls it Undefined Behavior.

From 6.3.2.3.8
"A pointer to a function of one type may be converted to
a pointer to a function of another type and back again;
the result shall compare equal to the original pointer.
If a converted pointer is used to call a function whose
type is not compatible with the pointed-to type, the
behavior is undefined."


Question: In what ways could the function types be different, and still
be compatible? I'm guessing it's safe if the conversion adds const
and/or volatile qualifiers to some parameters. Could you replace a void*
parameter with a char* parameter? A signed integer with an unsigned
integer? What if the real function returns a value, but the pointer it's
called through is to a void function type?

I have my suspicions about the answers to these questions, but I'd like
to know if I'm wrong.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #5
Kevin Goodsell wrote:

Al Bowers wrote:

The Standard explicitly calls it Undefined Behavior.

From 6.3.2.3.8
"A pointer to a function of one type may be converted to
a pointer to a function of another type and back again;
the result shall compare equal to the original pointer.
If a converted pointer is used to call a function whose
type is not compatible with the pointed-to type, the
behavior is undefined."
Question: In what ways could the function types be different, and still
be compatible? I'm guessing it's safe if the conversion adds const
and/or volatile qualifiers to some parameters. Could you replace a void*
parameter with a char* parameter? A signed integer with an unsigned
integer? What if the real function returns a value, but the pointer it's
called through is to a void function type?

I have my suspicions about the answers to these questions, but I'd like
to know if I'm wrong.


On the level of the source code being considered correct, they cannot be
different.

On the level of executing undefined behavior in a not-pernicious
manner, whenever nothing happens that would cause execution to halt - like
when the shape of the parameters are the same. You could mix up
ints, longs and pointers on some architectures.

But it's still wrong :)

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

--
Les Cargill
Nov 13 '05 #6
Keith Thompson <ks***@mib.or g> wrote in message news:<ln******* *****@nuthaus.m ib.org>...
fi*******@theli nuxlink.net (Barbrawl McBribe) writes:
Is is possible to use typedefs to cast function pointers? I think I
saw this in the WINGs src; grep for '(hashFunc)'. So far, trying to
use a typedef to cast function pointers so that a return value of
float is changed to float seems not to work; I belive it was like
this:

typedef int (*foo) (int);

function_ptr_ba r = (foo)function_t hat_returns_flo at;
I presume you mean "so that a return value of float is changed to
int".


Yes. This is just messing around; I deem it has no practical
application.

Why would you want to do this?
It's a CS thing... Personally, I just want to try what I can, and I
will learn from even stupid sh*t. Remember, as Carl Sagan said, that
fundamental science can be a prerequisite for applied science.

You can probably make it work, but it's extremely unsafe and non-portable.
Definitely...

Basically, you're trying to lie to the compiler.
That's a clever way of saying it.

At best, you'll call function_that_r eturns_float() and treat its result as an int (not a numeric conversion, but a
reinterpretatio n of the bits). At worst, the calling conventions will
differ, and arbitrarily bad things will happen, from getting
meaningless garbage to crashing your program.


Well, the casts in the WINGs source are casting to what the function
*was* in the first place, if you see what I mean (as in from a return
value of void * to void * and likewise for the arguments). I
eliminated them, recompiled, and all was well. I can conclude
reasonably that they are there for clarity.
Nov 14 '05 #7
On Sun, 07 Dec 2003 22:39:01 GMT, Kevin Goodsell
<us************ *********@never box.com> wrote:
Al Bowers wrote:

The Standard explicitly calls it Undefined Behavior.

From 6.3.2.3.8
"A pointer to a function of one type may be converted to
a pointer to a function of another type and back again;
the result shall compare equal to the original pointer.
If a converted pointer is used to call a function whose
type is not compatible with the pointed-to type, the
behavior is undefined."


Question: In what ways could the function types be different, and still
be compatible? I'm guessing it's safe if the conversion adds const
and/or volatile qualifiers to some parameters. Could you replace a void*
parameter with a char* parameter? A signed integer with an unsigned
integer? What if the real function returns a value, but the pointer it's
called through is to a void function type?

Two *prototyped* function types are compatible (only) if corresponding
parameters are compatible ignoring top-level qualification and after
"adjustment " to pointer of (declared) array or function parameters,
and both or neither end with ellipsis (variadic). void* and char* are
not compatible according to the type rules, although they are required
to have the same representation and so substituting them will work in
practice unless the implementation is odd (or perverse) enough to pass
them differently, and the same for corresponding signed and unsigned
integers. Including plain/signed/unsigned char, and pointers thereto.

An incomplete or "forward declared" struct or union is compatible with
the completed type, and (nearly) identically declared such types or
enums in different t.u.s are compatible although formally they are not
the same type. An enum is compatible with an implementation-defined
integer type, usually int. Array of unspecified (or in C99 VLA) bound
is compatible (at compile time) with array of fixed bound. I think
that's all the freedom you officially have.

The more complicated cases are compatibility between or with
unprototyped function types, e.g.:
int foo (int x, double y);
int foo (x, y) short x; float y; { blah blah }
are compatible, and a pointer to unspecified-args function:
int (*ptr)() = foo;
can be silently converted from any function pointer, but can correctly
be used to call only a function with no arguments (and returning int).
For unprototyped definitions, the void*-char* and signed-unsigned
cases are permitted in 6.5.2.2, which is more detailed than 6.3.3.8.

Both prototyped and unprototyped declarations (and definitions) of a
function do define the return type, and (so) function types with
different return types are never compatible.
- David.Thompson1 at worldnet.att.ne t
Nov 14 '05 #8
fi*******@theli nuxlink.net (Barbrawl McBribe) writes:
Keith Thompson <ks***@mib.or g> wrote in message
news:<ln******* *****@nuthaus.m ib.org>...

[...]
At best, you'll call function_that_r eturns_float() and treat its
result as an int (not a numeric conversion, but a reinterpretatio n
of the bits). At worst, the calling conventions will differ, and
arbitrarily bad things will happen, from getting meaningless
garbage to crashing your program.


Well, the casts in the WINGs source are casting to what the function
*was* in the first place, if you see what I mean (as in from a return
value of void * to void * and likewise for the arguments). I
eliminated them, recompiled, and all was well. I can conclude
reasonably that they are there for clarity.


Hmm. I don't know what WINGs might be, but simply casting a function
to its own type isn't going to do anything for clarity. On the
contrary, it's confusing and error-prone. Rather than letting the
compiler verify the function type, the cast forces the compiler to
assume that it's of the right type and inhibits error checks.

*Unless* it's casting function pointers to their proper types. I can
imagine a program keeping function pointers of various types in a data
structure, where each element stores a function pointer (cast to some
generic function pointer type) and an indication of the function's
actual type. A calling routine would then cast the function pointer
back to its original type. Something like that might be used in an
interpreter, for example.

It's something you might consider if you *really* know what you're
doing.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 14 '05 #9
On Fri, 12 Dec 2003 22:04:55 GMT, I wrote, and apparently slipped at
least one cog while doing so:
<snip>
The more complicated cases are compatibility between or with
unprototyped function types, e.g.:
int foo (int x, double y);
int foo (x, y) short x; float y; { blah blah }
are compatible, and a pointer to unspecified-args function:
int (*ptr)() = foo;
can be silently converted from any function pointer, but can correctly
be used to call only a function with no arguments (and returning int).


Of course it can be used to call any oldstyle definition, or one with
prototyped parameter types not altered by the default promotions and
not variadic. But (in either case) they do have to return int.

- David.Thompson1 at worldnet.att.ne t
Nov 14 '05 #10

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

Similar topics

2
3627
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 support. (first i compiled them with g++3.x. ERR means compiler will bark, otherwise it does accept it. Then the Comeau C/C++ 4.3.3 comes)
14
4628
by: dreamcatcher | last post by:
I always have this idea that typedef a data type especially a structure is very convenient in coding, but my teacher insisted that I should use the full struct declaration and no further explanations, so I wonder is there any good using typedef ? and I also know that when a data type being typedefed become an abstract data type, so what exactly is an abstract data type, is it any good ? -- Posted via http://dbforums.com
30
4240
by: stephen henry | last post by:
Hi all, I have a question that I'm having difficulty answering. If I have a struct: typedef struct my_struct_tag{ struct my_other_struct *other; } my_struct_tag
2
3052
by: Immo Birnbaum | last post by:
Hi, I'm trying to solve a programming lab assignment for my college C programming course, but as they taught us two semesters of Java before teaching us any C, I'm having problems with all the aspects of pointers. I'd appreciate if anybody could help me with the following problem: I tried to learn how to use malloc, free, and the * and & operators. I started with a few simple lines of code like:
2
2928
by: Mehta Shailendrakumar | last post by:
Hi all, Have alook at two different declarations below: typedef unsigned char uc; typedef void (*fptr) (void); The first declaration has a left part which is a C keyword: "unsigned char" and the declaration is clarly understandable.
14
2244
by: yang__lee | last post by:
Hi, You all know typedef typedef struct g { int a; int b; } google;
12
4637
by: Googy | last post by:
Hi!! Can any one explain me the meaning of following notations clearly : 1. typedef char(*(*frpapfrc()))(); frpapfrc f; 2. typedef int (*(arr2d_ptr)()); arr2d_ptr p; 3. typedef int (*(*(*ptr2d_fptr)()))();
13
2803
by: William Xu | last post by:
This won't compile: ,---- | int foo(char *p) | {} | | int main(int argc, char *argv) | { | typedef int (*FUNC)(void *); |
16
2766
by: mdh | last post by:
A quick ? :-) question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense? Sorry if this is somewhat general, but there are no exercises ( not that I am asking for...
0
8857
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8764
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8546
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
8633
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...
1
6186
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
5654
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
4180
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2762
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
1993
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.