Is there a way around "incompatible pointer" warnings for void** arguments ?

Jonathan Wakely jwakely.gcc@gmail.com
Fri May 23 12:27:00 GMT 2014


On 23 May 2014 13:01, Chris Hall wrote:
> Where I have something along the lines of:
>
>   typedef struct foo* foo

(I really hope you don't use  the same name for a type and a pointer
to that type in real code!)

>   void
>   create(void** p_n, size_t s)
>   {
>     *p_n = malloc(s) ;
>   } ;
>
>   .....
>   {
>     foo bar ;
>     .....
>     create(&bar, 86) ;
>     .....
>   } ;
>
> I get the helpful warning "passing argument 1 of 'create' from incompatible pointer type".  (This is, obviously, an artificial example.  The problem arises with any function which takes a void** argument.)
>
> Don't get me wrong, I'm a big fan of this warning, in general.  I suspect the reason is something deep in C... but it doesn't make full sense to me.

You can do it via a series of valid (and in this case, safe) conversions:

  foo bar ;
  void* vbar = bar;
  create(&vbar, 86) ;
  bar = vbar;


> And (bizarrely, IMHO):
>
>    create(&((void*)bar), 86) ;
>
> is an error: "lvalue required as unary '&' operand" ?!?

The cast creates a temporary object of type void*, the error is
because you cannot take the address of a temporary.

> Pointers to pointers and, worse yet, chains of pointers to pointers require care (and my head hurts).  So I appreciate all the help the compiler can give me to spot problems early.  Having to cast to (void**) feels like taking the seat belt off and pressing the pedal to the metal :-(

I seriously suggest using C++ instead, the compiler gives you more
help with type safety, and provides features to avoid many common
mistakes while fiddling with pointers:

template<typename T>
void create(T** p)
{
  *p = (T*)malloc(sizeof(T));
}

foo bar;
create(&bar);

That gets the size and the type correct automatically (assuming the
magic number 86 in your code was sizeof(struct foo)). But in C++
there's no need to write that code anyway:

struct foo { };
foo* bar = new foo;

(People will tell you that C++ is over-complicated and gives you more
than enough rope to hang yourself with ... fine, don't use all those
features. It's still a better C even if you only use a fraction of the
language.)



More information about the Gcc-help mailing list