matkas
matkas

Reputation: 85

Is Cast to void** needed?

I have the compiler complaining (warning) about the folowing.

Am I missing something? Because I thought this didn't need a cast

char* CurrentCh  = some ptr value;
int size;

size = func(&CurrentCh);

with func defined like this

int func(void** ptr);

Compiler warning:

passing argument 1 of 'func' from incompatible pointer type

Thx

Upvotes: 4

Views: 492

Answers (4)

Christoph
Christoph

Reputation: 169633

The cast is necessary as what you do is a form of type punning: You reinterpret the memory which is pointed to from char * to void *.

For these types, the C standard guarantees that this actually works as char * and void * have the same representation. For other type combinations, this may not be the case.

The relevant parts of the standard are section 6.2.5, §27

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

and less relevant (but perhaps also interesting) section 6.3.2.3, §7

A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

Anything beyond that is implementation-specific.

Upvotes: 3

Alok Singhal
Alok Singhal

Reputation: 96151

In C, void * is the generic pointer type. But void ** is not a generic pointer-to-pointer type! If you want to be able to pass a pointer to a pointer in a generic way, you should use void * anyway:

#include <stdio.h>

void func(void *ptr)
{
    char **actual = ptr;
    const char *data = *actual;
    printf("%s\n", data);
}

int main(void)
{
    char *test = "Hello, world";
    func(&test);
    return 0;
}

Upvotes: 4

Joel
Joel

Reputation: 5674

In C, any pointer can downcast to void*, but not to void**. You will need an explicit cast.

Upvotes: 0

Ferruccio
Ferruccio

Reputation: 100698

In C you can pass any pointer type to a function that expects a void*. What it says is "I need a pointer to something, it doesn't matter what it points to". Whereas void** says "I need a pointer to a void*, not a pointer to another pointer type".

Upvotes: 7

Related Questions