Menu
Forums
New posts
Search forums
Members
Current visitors
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Menu
Log in
Register
Install the app
Install
Forums
Archive
Archive
C Programming
Functions taking pointers to different types as arguments
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="Keith Thompson" data-source="post: 2398246"><p>Yes, but if you call qsort() with a comparison function that takes</p><p>pointers to structs, you'll invoke undefined behavior.</p><p></p><p>Different pointer types can be converted to each other (in some cases)</p><p>*if* the compiler has enough information to do the conversion, i.e.,</p><p>if the compiler knows both the source and target pointer types. If</p><p>you hide this information from the compiler by using a single pointer</p><p>type to refer to two distinct function types, the compiler will</p><p>complain. If you then use casts to force the compiler to accept the</p><p>mistyped pointer, you're lying to the compiler, and it will get its</p><p>revenge by giving you undefined behavior.</p><p></p><p>As it happens, you're likely to get away with it on most modern</p><p>systems, since many of them use only a single internal representation</p><p>for all pointer types. Don't think of this permissiveness as the</p><p>implementation being friendly; think of it as the implementation being</p><p>actively hostile by failing to diagnose errors that will show up at</p><p>the most inconvenient possible moment, several years from now, when</p><p>you try to port the code to a less "friendly" implementation.</p><p></p><p>There's no direct way to do what you're trying to do, but there are a</p><p>number of indirect ways to do it. You can store a pointer to either</p><p>the fgetc or gzgetc function in a single variable of some</p><p>pointer-to-function type, but you have to convert it back to the</p><p>proper type before performing a call through the function. That means</p><p>you have to know what the proper type is. Rather than using just a</p><p>pointer, use a struct consisting of a function pointer and a flag of</p><p>some sort that tells you the actual type of the function you're</p><p>pointing to. C doesn't let you store types directly, but you could</p><p>use an enumeration and choose what to do based on its value. You can</p><p>then do something like:</p><p></p><p> typedef void (*func_ptr)(void);</p><p> typedef int (*fgetc_ptr)(FILE*);</p><p> typedef int (*gzgetc_ptr)(void*);</p><p></p><p> if (straight) {</p><p> getter.func = (func_ptr)fgetc;</p><p> getter.kind = 'f';</p><p> }</p><p> else {</p><p> getter.func = (func_ptr)gzgetc;</p><p> getter.kind = 'g';</p><p> }</p><p></p><p> ...</p><p> </p><p> nextchar = (getter.kind == 'f' ? ((fgetc_ptr)getter.func)(file)</p><p> : ((gzgetc_ptr)getter.func)(file));</p><p></p><p>Wrap some of this in macros if you like.</p><p></p><p>Of course, as long as you're selecting the type based on the "kind",</p><p>you probably might as well select the function that way and avoid the</p><p>confusion of storing a pointer to it. The best approach depends on</p><p>the design of your application.</p></blockquote><p></p>
[QUOTE="Keith Thompson, post: 2398246"] Yes, but if you call qsort() with a comparison function that takes pointers to structs, you'll invoke undefined behavior. Different pointer types can be converted to each other (in some cases) *if* the compiler has enough information to do the conversion, i.e., if the compiler knows both the source and target pointer types. If you hide this information from the compiler by using a single pointer type to refer to two distinct function types, the compiler will complain. If you then use casts to force the compiler to accept the mistyped pointer, you're lying to the compiler, and it will get its revenge by giving you undefined behavior. As it happens, you're likely to get away with it on most modern systems, since many of them use only a single internal representation for all pointer types. Don't think of this permissiveness as the implementation being friendly; think of it as the implementation being actively hostile by failing to diagnose errors that will show up at the most inconvenient possible moment, several years from now, when you try to port the code to a less "friendly" implementation. There's no direct way to do what you're trying to do, but there are a number of indirect ways to do it. You can store a pointer to either the fgetc or gzgetc function in a single variable of some pointer-to-function type, but you have to convert it back to the proper type before performing a call through the function. That means you have to know what the proper type is. Rather than using just a pointer, use a struct consisting of a function pointer and a flag of some sort that tells you the actual type of the function you're pointing to. C doesn't let you store types directly, but you could use an enumeration and choose what to do based on its value. You can then do something like: typedef void (*func_ptr)(void); typedef int (*fgetc_ptr)(FILE*); typedef int (*gzgetc_ptr)(void*); if (straight) { getter.func = (func_ptr)fgetc; getter.kind = 'f'; } else { getter.func = (func_ptr)gzgetc; getter.kind = 'g'; } ... nextchar = (getter.kind == 'f' ? ((fgetc_ptr)getter.func)(file) : ((gzgetc_ptr)getter.func)(file)); Wrap some of this in macros if you like. Of course, as long as you're selecting the type based on the "kind", you probably might as well select the function that way and avoid the confusion of storing a pointer to it. The best approach depends on the design of your application. [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
C Programming
Functions taking pointers to different types as arguments
Top