variables and pointers.. noob question..

S

streamkid

i'm a learning newbie at c++... and i have the following question...
reading some source code, i saw this:

int function(const void * one, const void * two)
{
int var1, var2;
var1 = *((int*)one);
var2 = *((int*)two);
/* sm other code here*/
}

my question is about the rhs of var1 assigment. -> *((int*)one);
i am sure about what it does ;P
my question is how this is done.. i mean, why so many dereference
operators and so many parentheses? isn't that to complicated??

can someone explain how this works??
tia, streamkid :)
 
S

Stuart Golodetz

i'm a learning newbie at c++... and i have the following question...
reading some source code, i saw this:

int function(const void * one, const void * two)
{
int var1, var2;
var1 = *((int*)one);
var2 = *((int*)two);
/* sm other code here*/
}

my question is about the rhs of var1 assigment. -> *((int*)one);
i am sure about what it does ;P
my question is how this is done.. i mean, why so many dereference
operators and so many parentheses? isn't that to complicated??

can someone explain how this works??
tia, streamkid :)

Well...

one is of type const void * : we can't dereference that (What's a "void"?!
No, really, don't answer that anyone...)

But we happen to know that one really points to an int and we want to get at
that int. "Hmm", we say, "if only we had a pointer of type int * to that
int..." As it happens, we can obtain one by casting one to type int *, i.e.
by writing (int*)one. But this still hasn't given us our pointed-to int. For
that, we have to dereference this new int *, which is why we write
*((int*)one), just as if we had a pointer p and we were dereferencing that
using *p.

Do you see what's going on?

Hope this helps,
Stu
 
M

Marcus Kwok

i'm a learning newbie at c++... and i have the following question...
reading some source code, i saw this:

int function(const void * one, const void * two)
{
int var1, var2;
var1 = *((int*)one);
var2 = *((int*)two);
/* sm other code here*/
}

my question is about the rhs of var1 assigment. -> *((int*)one);
i am sure about what it does ;P
my question is how this is done.. i mean, why so many dereference
operators and so many parentheses? isn't that to complicated??

can someone explain how this works??

Let's look at it step-by-step:

one is a const void*, so it is a pointer to some unknown type, and this
unknown type is const so it cannot be changed in the context of this
function.

(int*)one is a cast of this unknown pointer. It assumes that one is a
pointer to an int, and casts one as such.

*((int*)one) dereferences this pointer. Since one has been casted to a
pointer to int, dereferencing this will yield an int (assuming that the
pointer is valid, and that it is indeed pointing to an int).

The way this function is written is very unsafe. You have no guarantee
that the pointer is actually pointing to an int. The function also does
not check for the possibility of a null pointer.

Pointers are an advanced topic. C++ has many techniques that will allow
you to avoid using pointers in many cases, but for some other cases they
may be necessary. However, in the cases where they are necessary, it
may be possible to replace them with a smart pointer of some kind, which
can help alleviate some of the complexity of using them properly.
 
S

streamkid

firstly, thank both of you for the answers :)
Stuart Golodetz

As it happens, we can obtain one by casting one to type int *, i.e. by writing (int*)one. But this still hasn't >given us our pointed-to int. For that, we have to dereference this new int *, which is why we write >*((int*)one), just as if we had a pointer p and we were dereferencing that using *p.

Do you see what's going on?

so, Stuart, i think i do.. :)
confusing though.. :$
if we 'd written var1 = *one; it wouldn't have worked, right? :)
got it!:)
Marcus Kwok

The way this function is written is very unsafe. You have no guarantee that the pointer is actually pointing >to an int. The function also does not check for the possibility of a null pointer.

C++ has many techniques that will allow you to avoid using pointers in many cases, but for some other >cases they may be necessary. However, in the cases where they are necessary, it may be possible to >replace them with a smart pointer of some kind, which can help alleviate some of the complexity of using >them properly.

so, Marcus, about the first quote, it couldn't be null pointer and is
sure that its 100% a int... it's the nature of the problem :)

this function is going to be passed l8r on the app as an arg on qsort,
and if i am not wrong qsort requires all this... if no, how could have
this been written?
 
S

Stuart Golodetz

firstly, thank both of you for the answers :)


so, Stuart, i think i do.. :)
confusing though.. :$
if we 'd written var1 = *one; it wouldn't have worked, right? :)
got it!:)

Right, because you can't dereference a void *.

Regards,
Stu

P.S. For what it's worth, might be better to reply to each person
individually, gets confusing for people otherwise :)

<snip>
 
S

Salt_Peter

i'm a learning newbie at c++... and i have the following question...
reading some source code, i saw this:

int function(const void * one, const void * two)
{
int var1, var2;
var1 = *((int*)one);
var2 = *((int*)two);
/* sm other code here*/
}

my question is about the rhs of var1 assigment. -> *((int*)one);
i am sure about what it does ;P
my question is how this is done.. i mean, why so many dereference
operators and so many parentheses? isn't that to complicated??

can someone explain how this works??
tia, streamkid :)

break it down:
*(...) means dereference whatever pointer is in the brackets.
(int*)one is an old time cast that converts from void* to int*.
so the equivalent would be:
var1 = reinterpret_cast<int*>(one);

First off, pointers to void are basicly pointers to nothing. The goal
that such code has is to bypass the compiler's type-checking ability
which is stupid at best. Notice that a const void* is an oxymoron.
Since void is nothing, how can it be constant? And a pointer that is
non-mutable would have been written instead like so:
void* const

Why don't take a look at the proper equivalents:

using constant pointers to const integers:

int function(const int* const p_one, const int* const p_two)
{
int var1, var2;
var1 = *p_one; // dereferencing a pointer
var2 = *p_two;
/* sm other code here*/
}

or even better with references:

int function(const int& var1, const int& var2)
{
/* sm other code here*/
}
 
S

Stuart Redmann

i'm a learning newbie at c++... and i have the following question...
reading some source code, i saw this:

int function(const void * one, const void * two)
{
int var1, var2;
var1 = *((int*)one);
var2 = *((int*)two);
/* sm other code here*/
}

my question is about the rhs of var1 assigment. -> *((int*)one);
i am sure about what it does ;P
my question is how this is done.. i mean, why so many dereference
operators and so many parentheses? isn't that to complicated??

You're right, one pair of parenthesis is superflous. The number of
dereference operators is the minimal number possible, one. Speaking of
intricacy, it gets a bit worse if you avoid C style cast. If you did,
above statement had to be written like
var1 = *static_cast<const int*> (one);

Regards,
Stuart
 
D

David Harmon

On 20 Oct 2006 10:09:31 -0700 in comp.lang.c++,
this function is going to be passed l8r on the app as an arg on qsort,
and if i am not wrong qsort requires all this... if no, how could have
this been written?

You are right... but this is ancient unsafe C code that should
rarely be seen in the 21st century. Use std::sort, and write your
comparison function with the true argument types and no casts.
 
S

streamkid

when i saw this var1 = reinterpret_cast<int*>(one); i didn't know about
reinterpret_cast, so i googled..
it became more clear what exactly is done there.... :)

as i ve mentioned before, the function is going to be passed as an
argument to qsort (cstdlib)..
here [http://www.cplusplus.com/ref/cstdlib/qsort.html] says this:
void qsort ( void * base, size_t num, size_t width, int
(*fncompare)(const void *, const void *) );
i understand that qsort expects a function that takes as parameters two
const void *..
how can that be changed so we pass to qsort a function that takes
references?
in this case, it doesn't make big difference anymore (after learning
how it works ;P), but this may be usefull somewhere else i gues..
 
S

streamkid

soz, i didn't see your reply when i wrote my last..
i saw using sort from cstlib on a c++ competition, from last year.. i
thought they used "good" techniques.. =p
thx for the advice :)
 
D

Daniel T.

Stuart Redmann said:
You're right, one pair of parenthesis is superflous. The number of
dereference operators is the minimal number possible, one. Speaking of
intricacy, it gets a bit worse if you avoid C style cast. If you did,
above statement had to be written like
var1 = *static_cast<const int*> (one);

static_cast would be inappropriate in that context wouldn't it? I think
that is a reinterpret_cast.
 
R

red floyd

Daniel said:
static_cast would be inappropriate in that context wouldn't it? I think
that is a reinterpret_cast.

No, you can static_cast safely from void*, ***ASSUMING*** that your
void* really does point to whatever you're casting to.
 
M

Marcus Kwok

so, Marcus, about the first quote, it couldn't be null pointer and is
sure that its 100% a int... it's the nature of the problem :)

this function is going to be passed l8r on the app as an arg on qsort,
and if i am not wrong qsort requires all this... if no, how could have
this been written?

Well, if that's what qsort() requires then I guess you don't have much
choice. On the other hand, see David Harmon's reply, and also this item
from Stroustrup's FAQ:

Why use sort() when we have "good old qsort()"?
http://www.research.att.com/~bs/bs_faq2.html#sort
 
S

streamkid

hmm.. then i just continue working on qsort :)
and have std::sort as a knowledge :)
thanx guys, helped so much :)
 
M

Marcus Kwok

red floyd said:
No, you can static_cast safely from void*, ***ASSUMING*** that your
void* really does point to whatever you're casting to.

I'm inclined to agree, for example see C++ usage of malloc():

int* p = static_cast<int*>(malloc(sizeof(int)));
 

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
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top