void * pointers

R

Rahul

Hi Everyone,

There was a discussion on the need of void * in C and C++. In C, it
is a generic pointer which can be typecasted to and from that of other
types.

And it is developer's head ache to take care that the cast to and
from void * is correct. C++ enhanced type cast dynamic_cast doesn't
help in this case, as it needs the type information. This makes me
wonder, why make a cast to void * and pass the info to other
functions? Why not simply pass the direct pointer?

Does anyone know the reason where void* only can solve the problem?
 
B

Barry

Rahul said:
Hi Everyone,

There was a discussion on the need of void * in C and C++. In C, it
is a generic pointer which can be typecasted to and from that of other
types.

And it is developer's head ache to take care that the cast to and
from void * is correct. C++ enhanced type cast dynamic_cast doesn't
help in this case, as it needs the type information. This makes me
wonder, why make a cast to void * and pass the info to other
functions? Why not simply pass the direct pointer?

In C++, we don't use void* in this case, we use base_class* as
parameter, and we don't have to do explicit cast before passing it.

An good example why using void* in C is thread entry function,
an thread entry function often defined as following:

void entry_fn(void* param) // client programmer
{
// cast param to the exact type and use it
}

CRT function on Win32 to create a thread.

uintptr_t _beginthread(
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);

// client programmer create a thread like the following

_beginthread(entry_fn, 0, NULL);

entry_fn is also considered as callback function, _beginthread can't
foresee what kind of param, number of params that the client programmer
will use, so leave it to a generic type (void*).
 
J

john

Rahul said:
Hi Everyone,

There was a discussion on the need of void * in C and C++. In C, it
is a generic pointer which can be typecasted to and from that of other
types.

And it is developer's head ache to take care that the cast to and
from void * is correct. C++ enhanced type cast dynamic_cast doesn't
help in this case, as it needs the type information. This makes me
wonder, why make a cast to void * and pass the info to other
functions? Why not simply pass the direct pointer?

Does anyone know the reason where void* only can solve the problem?


In C generic programming is made by using void pointers and id
parameters. In C++ we use templates instead:


For example:

/*C */

void somefunc(void *p, char id)
{
if (id=='i')
/* ... */

if (id== 'n')
/* ... */
}


// C++
void somefunc(T &obj)
{
//...

}
 
J

john

Some corrections:

In C generic programming is made by using void pointers and id
parameters. In C++ we use templates instead:


For example:

/*C */

void somefunc(void *p, char id)
{
if (id=='i')
/* ... */
==> else if (id== 'n')
/* ... */
}


// C++
 
D

Dave Rahardja

Rahul said:
Hi Everyone,

There was a discussion on the need of void * in C and C++. In C, it
is a generic pointer which can be typecasted to and from that of other
types.

And it is developer's head ache to take care that the cast to and
from void * is correct. C++ enhanced type cast dynamic_cast doesn't
help in this case, as it needs the type information. This makes me
wonder, why make a cast to void * and pass the info to other
functions? Why not simply pass the direct pointer?

Does anyone know the reason where void* only can solve the problem?

As I see it, void* shows the pedigree of C++ as coming from C, a system
programming language.

While implementing very low level routines, there are cases where you
want to deal with a "bucket of bits" that is untyped. For example, the
following endian-reversing routine (inherently compiler- and
platform-dependent) may not care what the type is of the thing you're
reversing:

namespace Compiler_Dependent
{
void reverse_endian(void*, std::size_t size);
}

You can then add your own type-safe wrappers around it:

template <typename T>
inline void reverse_endian(T& item)
{
Compiler_Dependent::reverse_endian(&T, sizeof(T));
}

Other examples include raw-bytes buffer implementations.

-dr
 
A

Aragon

template <typename T>
inline void reverse_endian(T& item)
{
Compiler_Dependent::reverse_endian(&T, sizeof(T));
}

Whoops, reverse_endian(&item... of course.
 

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

No members online now.

Forum statistics

Threads
474,181
Messages
2,570,970
Members
47,537
Latest member
BellCorone

Latest Threads

Top