Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #60952

Re: Casting function pointers to different signatures

From James Kuyper <jameskuyper@verizon.net>
Newsgroups comp.lang.c
Subject Re: Casting function pointers to different signatures
Date 2015-04-23 17:10 -0400
Organization Self
Message-ID <55395FD4.90707@verizon.net> (permalink)
References <9938e88b-965b-4d07-8e86-62b3afa07849@googlegroups.com>

Show all headers | View raw


On 04/23/2015 04:39 PM, samuelallenalexander@gmail.com wrote:
> Suppose I have a generic array-printing function like this,
> 
> void print_array( void (*printer) (void *), void **array )
> {
>   for ( ; *array; array++ )
>     (*printer)(*array);
> }
> 
> And suppose I have a "print-with-brackets" function like this,
> 
> void print_with_brackets( char *x )
> {
>   printf( "[%s]\n", x );
> }
> 
> Is it legal/defined-behavior if I cast print_with_brackets to void (*) (void*) and pass it as the first argument to print_array, e.g. as in the following?
> 
> void print_abc( void )
> {
>   char **buf = malloc(sizeof(char*)*4);
>   buf[0] = "a", buf[1] = "b", buf[2] = "c", buf[3] = NULL;
>   print_array( (void (*) (void*))print_with_brackets, (void**)buf );
> }
> 

"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 referenced type, the
behavior is undefined." (6.3.2.3p8)

Passing it as an argument to print_array() is not a problem. However,
calling it inside print_array() through a pointer that a function type
that is incompatible with the actual type of print_with_brackets() has
undefined behavior. "void" is not compatible with "char", so "void*" is
not compatible with "char*"= (6.7.6.1p2), so void (*)(void*) is not
compatible with void (*)(char*) (6.7.6.3p15).

Note that buf in print_abc has the type char**, while array in
print_array() has the type void**. Those are incompatible types, too.

Now, void* and char* are required to have the same representation and
same alignment requirement (6.2.5p28). Footnote 47 notes that "The same
representation and alignment requirements are meant to imply
interchangeability as arguments to functions, return values from
functions, and members of unions.". However, that's merely a
non-normative suggestion. Nothing in the standard actually requires that
the types be interchangeable. They could, for example, be passed between
function using different registers.

As a practical matter, you can generally count on void* and char* to be
interchangeable - but I think you'd be doing better to make sure that
that the declared type for print_with_brackets() actually matches the
declared type for *printer in print_array(), and similarly for buf in
print_abc() and array in print_array(). Do the conversion from void* to
char* somewhere else (such as in the body of print_with_brackets()).

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Casting function pointers to different signatures samuelallenalexander@gmail.com - 2015-04-23 13:39 -0700
  Re: Casting function pointers to different signatures Barry Schwarz <schwarzb@dqel.com> - 2015-04-23 14:01 -0700
  Re: Casting function pointers to different signatures James Kuyper <jameskuyper@verizon.net> - 2015-04-23 17:10 -0400
    Re: Casting function pointers to different signatures samuelallenalexander@gmail.com - 2015-04-23 14:39 -0700
      Re: Casting function pointers to different signatures James Kuyper <jameskuyper@verizon.net> - 2015-04-23 18:04 -0400
        Re: Casting function pointers to different signatures samuelallenalexander@gmail.com - 2015-04-23 15:49 -0700
          Re: Casting function pointers to different signatures James Kuyper <jameskuyper@verizon.net> - 2015-04-23 19:22 -0400
            Re: Casting function pointers to different signatures samuelallenalexander@gmail.com - 2015-04-24 10:42 -0700
              Re: Casting function pointers to different signatures James Kuyper <jameskuyper@verizon.net> - 2015-04-24 14:18 -0400
                Re: Casting function pointers to different signatures samuelallenalexander@gmail.com - 2015-04-24 12:36 -0700
                Re: Casting function pointers to different signatures James Kuyper <jameskuyper@verizon.net> - 2015-04-24 15:50 -0400
                Re: Casting function pointers to different signatures Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-24 13:18 -0700
    Re: Casting function pointers to different signatures Siri Cruz <chine.bleu@yahoo.com> - 2015-04-23 16:08 -0700
      Re: Casting function pointers to different signatures Keith Thompson <kst-u@mib.org> - 2015-04-23 18:36 -0700
        Re: Casting function pointers to different signatures Siri Cruz <chine.bleu@yahoo.com> - 2015-04-23 19:00 -0700
          Re: Casting function pointers to different signatures raltbos@xs4all.nl (Richard Bos) - 2015-04-25 10:48 +0000
      Re: Casting function pointers to different signatures Tim Rentsch <txr@alumni.caltech.edu> - 2015-04-25 04:05 -0700
  Re: Casting function pointers to different signatures Lőrinczy Zsigmond <nospam@for.me> - 2015-04-24 06:51 +0200
  Re: Casting function pointers to different signatures Richard Damon <Richard@Damon-Family.org> - 2015-04-25 10:57 -0400

csiph-web