Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is void** an acceptable type in ANSI-C?

Tags:

c

void

I have seen a function whose prototype is:

int myfunc(void** ppt)

This function is called in a C file as a = myfunc(mystruct **var1);

where mystruct is typedef for one of structure we have.

This works without any compilation errors in MSVC6.0, But when I compile it with some other C compiler, it gives an error at the place where this function is called with error message:

Argument of type mystruct ** is incompatible with parameter of type void **

The argument of myfunc() is kept as void** because it seems to be a generic malloc kind of function to be called with various structure variable types for memory allocation

  1. Is there any type such as void ** allowed in C standard/any C compilers?
  2. How do I fix this? [I tried casting the function call argument to mystruct**, but it didn't work]

-AD

like image 892
goldenmean Avatar asked Oct 29 '08 09:10

goldenmean


2 Answers

The comp.lang.c FAQ addresses this issue in detail in Question 4.9. In short, they say it's not strictly portable to cast an arbitrary pointer-to-pointer to a void **; they go on to explain that "code like this may work and is sometimes recommended, but it relies on all pointer types having the same internal representation (which is common, but not universal)." They go on to explain that "any void ** value you play with must be the address of an actual void * value somewhere; casts like (void **)&dp, though they may shut the compiler up, are nonportable (and may not even do what you want)."

So, you can safely/portably achieve the desired behavior with code like:

some_type *var1 = foo();
void *tmp_void_ptr = (void *)var1;
myfunc(&tmp_void_ptr);
like image 182
George Eadon Avatar answered Sep 27 '22 20:09

George Eadon


void** is valid but, based on your error message, you probably have to explicitly cast the argument as follows:

mystruct **var1;
x = myfunc ((void**) var1);

That's because the myfunc function is expecting the void** type. While void* can be implicitly cast to any other pointer, that is not so for the double pointer - you need to explicitly cast it.

like image 36
paxdiablo Avatar answered Sep 27 '22 20:09

paxdiablo