void* questions

J

johny smith

I have never really understood the purpose of the void*.

I guess it is so different data types could for instance be passed into a
function. And then the function will re cast it to the correct data type?

I have an example here that does not seem to work.

I pass in an integer in one case and a float in another case.

When I pass the float, I would expect to get an answer of 5 but I get a huge
number that is not 5.

So, I was wondering if someone could tell me what I am doing wrong here?

Thanks.

I assume this is a strange way of using the void*, but I was just wanting to
practice using it in some way.

#include <iostream.h>


void f1( void* number );


int main()
{

int number;

float number2;

number2 = 5.25;

number = 5;

f1( &number );

f1( &number2 );

return 0;

}


void f1( void* number )
{
int* num;

num = (int*)number;

cout << *num << endl;


}
 
M

Matthew Del Buono

johny smith said:
I have never really understood the purpose of the void*.

I guess it is so different data types could for instance be passed into a
function. And then the function will re cast it to the correct data type?

I have an example here that does not seem to work.

I pass in an integer in one case and a float in another case.

When I pass the float, I would expect to get an answer of 5 but I get a huge
number that is not 5.

So, I was wondering if someone could tell me what I am doing wrong here?

Thanks.

I assume this is a strange way of using the void*, but I was just wanting to
practice using it in some way.

#include <iostream.h>


void f1( void* number );


int main()
{

int number;

float number2;

number2 = 5.25;

number = 5;

f1( &number );

f1( &number2 );

return 0;

}


void f1( void* number )
{
int* num;

num = (int*)number;

cout << *num << endl;


}

Well, first off, with C++ your use of void* has really diminished. Try
templates. For this sample:

template <class T>
void f1(T number)
{
cout << number;
}

Much safer and a lot more type strict. Furthermore, with void pointers, some
things get a bit crazy. You can't exactly just take a float pointer and cast
it to an integer pointer. To understand this, let's take the following
theoretical example:

The float you're passing in, in binary: 010101010010101101
(Note that's not a real number, just one I came up with)

The integer that results from it: 010101010010101101
(Note it hasn't changed)

Now let's do a REAL type cast (like float a = 5; cout <<(int)a;)

The float you pass in: 010101010101001
The integer that results: 01110101

(Note they are not the same)

This is the problem. Void pointers retain no knowledge of their type. As a
result, typecasting is not safe at all. Floats are interpreted differently
from ints, remember that. Because they are interpreted differently, it's a
big problem, and you're getting some really huge number. Templates are much
easier to work with and much safer.

Good luck
-- Matt

P.S. If you REALLY must use a pointer to void to cast something, try a
reinterpret_cast<>. It's just the C++ way of doing something insane like
that ... but I don't see any purpose for it -- ever.
 
J

JKop

johny smith posted:
I have never really understood the purpose of the void*.

I guess it is so different data types could for instance be passed into
a function. And then the function will re cast it to the correct data
type?

I have an example here that does not seem to work.

I pass in an integer in one case and a float in another case.

When I pass the float, I would expect to get an answer of 5 but I get a
huge number that is not 5.

So, I was wondering if someone could tell me what I am doing wrong
here?

Thanks.

I assume this is a strange way of using the void*, but I was just
wanting to practice using it in some way.

#include <iostream.h>


void f1( void* number );


int main()
{

int number;

float number2;

number2 = 5.25;

number = 5;

f1( &number );

f1( &number2 );

return 0;

}


void f1( void* number )
{
int* num;

num = (int*)number;

cout << *num << endl;


}


What you're doing is exactly what my accessor_cast does (See the thread
entitled "accessor_cast"). You've got a float, but you're accessing in the
way in which an integer should be accessed. Long story short, the bit
pattern for a float of value 5 is not equal to the bit pattern for an int of
value 5.


-JKop
 
N

nmtop40

Matthew Del Buono said:
P.S. If you REALLY must use a pointer to void to cast something, try a
reinterpret_cast<>. It's just the C++ way of doing something insane like
that ... but I don't see any purpose for it -- ever.

There is a purpose, and that is in writing "opaques", eg streaming
binary, although I prefer to give the class factories a way of
creating their classes from the opaque, and getting the classes to
output opaque themselves. That is the ideal, but in the real world you
sometimes need high performance and a cast can occasionally give you
that little bit extra.
 
R

Rolf Magnus

johny said:
I have never really understood the purpose of the void*.

It's only rarely needed in C++.
I guess it is so different data types could for instance be passed
into a function. And then the function will re cast it to the correct
data type?

You could use it for that, but why not just use overloaded functions
instead?
I have an example here that does not seem to work.

I pass in an integer in one case and a float in another case.

When I pass the float, I would expect to get an answer of 5 but I get
a huge number that is not 5.
So, I was wondering if someone could tell me what I am doing wrong
here?

You're misunderstanding what the cast means. You're converting the
pointer, not the data it points to. When you wrote 5.25 to number2, the
compiler saved a bit pattern into that variable that represents that
value as float. In the function, you just interpret that exact same bit
pattern as an int. No proper conversion to an int value is done.
Therefore you get a bogus value. Basically, C++ doesn't even guarantee
that the pointer conversion itself works. It's only guaranteed that you
can do a lossless conversion of a pointer to an object into a void* and
back into the original type.
Btw: You should stick to the C++ cast and not use the C-style cast. In
this case, reinterpret_cast should be the right one. But again, it's
only rarely needed - mostly in low-level code that needs to do some
binary I/O. But you should not use it without knowing the consequences.
 
M

Matthew Del Buono

nmtop40 said:
"Matthew Del Buono" <[email protected]> wrote in message

There is a purpose, and that is in writing "opaques", eg streaming
binary, although I prefer to give the class factories a way of
creating their classes from the opaque, and getting the classes to
output opaque themselves. That is the ideal, but in the real world you
sometimes need high performance and a cast can occasionally give you
that little bit extra.

Okay, maybe "ever" was an overstatement, but it's rarely needed. For most
situations you won't need a cast like that...

-- Matt
 

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,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top