Typecasting void*

J

Jack Hopson

Hi

I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

There is also lots of code that relies on implicit typecasting of void*.

Which is preferable? Are there situations to choose one way over the
other?

Thanks.
 
Ö

Öö Tiib

I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

This is likely C code you see there. In C++ you very rarely need to
use void*, when dealing with some C library or API. On such cases do
not use C-style casts use static_cast.
There is also lots of code that relies on implicit typecasting of void*.

Pointer to any non-cv qualified object implicitly converts to void*.
It is pointless to use explicit cast to void*. Especially in C code,
where you do not have C++ casts and so you may accidentally cast away
constness.
Which is preferable? Are there situations to choose one way over the
other?

Since casting to void* and from void* are different operations i do
not understand that question.
 
J

Jens Thoms Toerring

In comp.lang.c Jack Hopson said:
I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

Casting the result of malloc() is never needed (unless you're
programming in C++ and not C). It just keeps the compiler from
issuing a warning when no declaration of malloc() is in scope
(which may result in an ugly and hard to find bug).
There is also lots of code that relies on implicit typecasting of void*.
Which is preferable? Are there situations to choose one way over the
other?

Since a void pointer is automatically converted to the type
of pointer its assigned to is nearly never needed to cast a
void pointer and I would avoid adding a cast since to me a
cast is an indication that something potentially dangerous is
going on that may require closer scrutiny. The only place a
cast is necessary is when the compiler can't derive what you
want by itself or you would have to do arithmetic on a void
pointer which is not allowed. One possility is that you have
e.g. a pointer that you know points to an array of ints but
which the compiler does not know, e.g. because the void poin-
ter was received as a function argument. If you then need the
address of the i-th element of the int array then you have to
cast:

addr_of_ith_elem = ( int * ) void_ptr + i;

or

addr_of_ith_elem = ( char * ) void_ptr + i * sizeof( int );

Regards, Jens
 
S

Seebs

I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

There is also lots of code that relies on implicit typecasting of void*.

Which is preferable? Are there situations to choose one way over the
other?

You posted this to one group where one is clearly superior, and another
group where the other is clearly superior.

I think that pretty much summarizes it.

(Howdy, C++ folks! Let's all stun the onlookers by NOT getting into a
huge flame war about this, 'k?)

-s
 
J

Johannes Schaub (litb)

Jack said:
Hi

I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

There is also lots of code that relies on implicit typecasting of void*.

What is "implicit typecasting"? I have always never heard about it (note the
pun).
Which is preferable? Are there situations to choose one way over the
other?

Do you say you want to advertise doing this one?

void *p = (void*)ptr;

Please, this is horrible.
 
L

lawrence.jones

Jack Hopson said:
I see a lot of code that explicitily typecasts void* to a specific
pointer type eg a pointer returned by malloc.

There is also lots of code that relies on implicit typecasting of void*.

Which is preferable? Are there situations to choose one way over the
other?

The answer is different for C and C++. In C, the concensus is that you
should never use the cast. In C++, the cast is required by the
language.
 
E

Ersek, Laszlo

The answer is different for C and C++. In C, the concensus is that you
should never use the cast. In C++, the cast is required by the
language.

(Sorry if this was already mentioned or is irrelevant.) I think an
explicit cast from (void*) may be necessary when crossing an ellipsis
(...). I'm reminded of <http://c-faq.com/null/nullreq.html> and where that
links. In general, any situation that can be illustrated by printf()'s
"%n" conversion specifier.

lacos
 
K

Keith Thompson

William Ahern said:
I don't follow. Why would casting to or from a void pointer be required
there? Why would casting be required at all except for casting NULL, which
might be interpreted as an int rather than a null pointer constant?

It depends on what type the called function is looking for (i.e., the
second argument it passes to the va_arg() macro). If the function
is looking for a void* argument, an expression that's already of
type void* doesn't need a cast. If the function is looking for,
say, an int*, you have to pass an int* argument; in some cases,
a cast might be the best way to do that.

On the other hand, if you're calling printf with "%n", it's unlikely
that the expression you want to pass is going to be of type void*
in the first place.
 
E

Ersek, Laszlo

It depends on what type the called function is looking for (i.e., the
second argument it passes to the va_arg() macro). If the function is
looking for a void* argument, an expression that's already of type void*
doesn't need a cast. If the function is looking for, say, an int*, you
have to pass an int* argument; in some cases, a cast might be the best
way to do that.

On the other hand, if you're calling printf with "%n", it's unlikely
that the expression you want to pass is going to be of type void* in the
first place.

I agree. That's why I used the word "illustrate"; I was too lazy to
concoct an example. I still can't find anything better than the following
contrieved one:

Consider a struct that carries a pointer-to-void (opaque data pointer in a
callback struct, or in some configuration or context structure, or in an
intrusive container node). One might be tempted to pass that pointer
directly to a function with variable arguments, because he happens to know
at that point that the type of the object to be modified beneath the
pointer-to-void is exactly what the vararg function will expect. However,
va_arg() doesn't convert, it reinterprets -- it lacks the source type.

A more common example -- which I didn't mention before because the OP
asked about the inverse direction -- is the "%p" conversion specifier.
Addresses of dynamically allocated structures are regularly printed, and
they need conversion.

Cheers,
lacos
 
K

Keith Thompson

Ersek said:
I agree. That's why I used the word "illustrate"; I was too lazy to
concoct an example. I still can't find anything better than the following
contrieved one:

Consider a struct that carries a pointer-to-void (opaque data pointer in a
callback struct, or in some configuration or context structure, or in an
intrusive container node). One might be tempted to pass that pointer
directly to a function with variable arguments, because he happens to know
at that point that the type of the object to be modified beneath the
pointer-to-void is exactly what the vararg function will expect. However,
va_arg() doesn't convert, it reinterprets -- it lacks the source type.
Right.

A more common example -- which I didn't mention before because the OP
asked about the inverse direction -- is the "%p" conversion specifier.
Addresses of dynamically allocated structures are regularly printed, and
they need conversion.

Yup.

Note that, on many (most?) systems, all pointers have the same
representation, so the lack of a required conversion isn't going to
cause any visible problems.
 
S

Seebs

I don't follow. Why would casting to or from a void pointer be required
there? Why would casting be required at all except for casting NULL, which
might be interpreted as an int rather than a null pointer constant?

Because different pointers might be of different sizes, so if you don't cast
to the right pointer type, you might pass an object which was not compatible
with (void *) where a function was expecting a (void *).

-s
 
B

Ben Bacarisse

Seebs said:
Because different pointers might be of different sizes, so if you don't cast
to the right pointer type, you might pass an object which was not compatible
with (void *) where a function was expecting a (void *).

Or different pointers may be the same size but use the bits differently.
 
P

Peter Nilsson

Jack Hopson said:
I see a lot of code that explicitily typecasts void* to
a specific pointer type eg a pointer returned by malloc.

I think it's safe to say that the majority of C programmers
who do this are aping other C programmers (even authors of
C books) who have also merely seen it, but never really
understood why they do it, let alone why they should or
shouldn't.

That isn't to say there aren't C programmers who know what
they're doing when they cast malloc. Some use C++ compilers
on C code precisely because of it's stricter requirements,
such as requiring function prototypes.
There is also lots of code that relies on implicit
typecasting of void*.

Which is preferable?

The whole point of the implicit conversion of void * in C
is to write generic code easily. Unfortunately, it's not a
fashion that has taken off in C. Despite the cleaner syntax,
it is still difficult to do, and most bugs and problems
centre around the type weakness that was meant to make
things simpler.

It is generally preferable to avoid casts. You generally
only use casts in C when it is obvious that they are correct.
Consider...

printf("%02X", 'A' + 0u);
printf("%02X", (unsigned) 'A');

Here %X requires an unsigned int. The cast ensures that, but
as the first statement shows, it's not strictly necessary.
This is an example of where most C programmers would actually
prefer to see the cast, because the implicit conversion in
the earlier argument is not immediately apparent at a glance.

Of course, it can be also done as...

unsigned x = 'A';
printf("%02X", x);

But that comes at the cost of declaring a variable. Apart
from the aesthetics, every line of code is an opportunity
for something (else) to go wrong. ;)

Everything is a trade-off. Casts are no exception.
 
N

Nick

The answer is different for C and C++. In C, the concensus is that you
should never use the cast. In C++, the cast is required by the
language.

About the only time in C when you might want to is in a function that
takes a generic argument (often a callback function). But even then,
it's always clearer to do:
int callback(void *data) {
struct data_block *db = data;
printf("%s\n",db->name);
}

than:
int callback(void *data) {
printf("%s\n",((struct data_block *)data)->name);
}

even if (because?!) the second is one line shorter and doesn't use the
extra variable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top