what is typecasting a pointer to the type (void *)p mean?

A

Abhishek

why do I see that in most C programs, pointers in functions are
accepted as:
int func(int i,(void *)p) where p is a pointer or an address which is
passed from the place where it is called. what do you mean by pointing
to a void and why is it done?
Aso, what happens when we typecast a pointer to another type. say for
example int *i=(char *)p;
under different situations? I am kind of confused..can anybody clear
this confusion by clearly explaining to me what actually is happening
out here?
Bye
 
M

Michael Rasmussen

int func(int i,(void *)p) where p is a pointer or an address which is
passed from the place where it is called. what do you mean by pointing to
a void and why is it done?
A pointer to a void is a pointer to an unqualified place in memory. If you
want to work with threads this is unavoidable. One of the reasons is a
way of transfering data from one process to another. You cannot do this
and at the same time preserve the type information. This also means that
the receiving process must know how to dereference the pointer - cast it
to a known type.

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void test_p(void *t)
{
int i;
char *text = (char *) t;
for (i = 0; i < 10; ++i)
printf("%s\n", text);
pthread_exit(NULL);
}

int main()
{
pthread_t t1 = 0;
char *text = "test";

printf("Howdy world!\n");
pthread_create(&t1, NULL, (void *)&test_p, (void *) text);
pthread_join(t1, NULL);
return 0;
}


Aso, what happens when we typecast a pointer to another type. say for
example int *i=(char *)p;
This is dangerous since you could loose information an depending on your
compiler could course either a warning or an error.
 
S

Scorpio

Abhishek said:
why do I see that in most C programs, pointers in functions are
accepted as:
int func(int i,(void *)p) where p is a pointer or an address which is
passed from the place where it is called. what do you mean by pointing
to a void and why is it done?

void pointer is a generic pointer, meaning that it can be used to store
address of any data type.

by (void*)p you are casting the address of p to void* type.
This is actually redundant. Typecasting is not necessary
while assigning value to a void* pointer.
Aso, what happens when we typecast a pointer to another type. say for
example int *i=(char *)p;

This should not even compile because you're trying to assign a wrong
type
of address to int *i.
under different situations? I am kind of confused..can anybody clear
this confusion by clearly explaining to me what actually is happening
out here?
Bye

Sharath A.V
 
A

Abhishek

Does this alsomean that I get the following flexibility?

like I can use the test_p function to accept different types of
pointers by typecasting them to type void * and later perform an action
depending on a particular flag variable I pass to the function?
like void test_p(void *t, int i)
{
int k;
if(i==1)
{
char *text = (char *) t;
for (k = 0; k < 10; ++k)
printf("%s\n", text);
}
else
{
int *j=(int *)t;
for(k=0;k<10;k++)
printf("%d\n",*j);
}

}

here...depending upon the value of 'i' I pass, I can take appropriate
action. However, I know that if I pass i=1, then I pass a pointer to a
string by typecasting to void * and if I pass i !=2 then I pass a
pointer to an integer by type casting the integer pointer to type void
*???
Pls clarify
 
E

Emmanuel Delahaye

Abhishek a écrit :
Does this alsomean that I get the following flexibility?

'flexibility' and 'void*' are often associated. Your intuition is correct.
like I can use the test_p function to accept different types of
pointers by typecasting them to type void * and later perform an action
depending on a particular flag variable I pass to the function?

Somehow, yes. Note that the conversion from/to void* doesn't need an
explicit typecast.
like void test_p(void *t, int i)
{
int k;
if(i==1)
{
char *text = (char *) t;

char *text = t;
if (text != NULL)
{
for (k = 0; k < 10; ++k)
printf("%s\n", text); }
}
else
{
int *j=(int *)t;

int *j = t;
if (j != NULL)
{
for(k=0;k<10;k++)
printf("%d\n",*j); }
}

}

here...depending upon the value of 'i' I pass, I can take appropriate
action.

Correct.
 
M

Michael Rasmussen

Does this alsomean that I get the following flexibility?

like I can use the test_p function to accept different types of pointers
by typecasting them to type void * and later perform an action depending
on a particular flag variable I pass to the function? like void
test_p(void *t, int i)
For this kind of problem I would recommend using a struct.

#include <stdio.h>

enum Kind {integer, string};

struct container {
enum Kind kind;
void *ptr;
};

void test_p(void *data)
{
struct container *c = (struct container *) data;
switch (c->kind) {
case integer:
printf("Received integer:\t%d\n", (int) c->ptr);
break;
case string:
printf("Received string:\t%s\n", (char *) c->ptr);
break;
default:
printf("Undefined data type\n");
}
}

int main()
{
struct container c;
char *text = "test";
int i = 1;

c.kind = string;
c.ptr = (void *)text;
test_p((void *) &c);
c.kind = integer;
c.ptr = (void *)i;
test_p((void *) &c);
return 0;
}
 
M

Michael Rasmussen

Somehow, yes. Note that the conversion from/to void* doesn't need an
explicit typecast.
Well, not always but in this situation it is mandatory:
void foo(void *t) {
printf("%s", (char *) t);
}

int main() {
char *t = "test";
foo(t);
return 0;
}

So might as well use explicit casting since it is a lot more readable for
an outsider which later has to maintain the code. IMHO
 
A

Al Balmer

Well, not always but in this situation it is mandatory:
void foo(void *t) {
printf("%s", (char *) t);
}

int main() {
char *t = "test";
foo(t);
return 0;
}

So might as well use explicit casting since it is a lot more readable for
an outsider which later has to maintain the code. IMHO

void foo(void *t) {
char *rt = t;
printf("%s", rt);
}
 
A

Abhishek

Thank you all for that wonderful explanation.
So, whats the difference between a null pointer and a pointer which is
pointing to void?
Are these same?
 
M

Michael Rasmussen

Thank you all for that wonderful explanation. So, whats the difference
between a null pointer and a pointer which is pointing to void?
Are these same?
A null pointer points to nothing - eg. you have a pointer of some type
which has not jet been assigned any value. A pointer to void is a pointer
of some unknown type assigned an address in memory.
 
K

Keith Thompson

Abhishek said:
Thank you all for that wonderful explanation.
So, whats the difference between a null pointer and a pointer which is
pointing to void?
Are these same?

Please don't top-post. Your response belongs below, or mixed with,
the article to which you're replying, and you should trim anything
that's not relevant to your response. This makes it much easier to
read each individual article from top to bottom.

No, they're very different things.

A null pointer is a particular pointer *value*. There's a null
pointer value for each pointer type (typically with the same
representation). A null pointer doesn't point to anything. (It's
typically, but not necessarily, represented as all-bits-zero.)

A void pointer is a pointer *type*, declared as "void*". It's a
generic pointer type. An object of type void* can point to any
object, or it can have a null pointer value.

You should read sections 4 and 5 of the comp.lang.c FAQ, available at
<http://www.c-faq.com/>. In fact, you should read the whole thing.
 
F

Flash Gordon

Michael said:
A null pointer points to nothing - eg. you have a pointer of some type
which has not jet been assigned any value.

No, a pointer that has not been assigned any value is *not* a null
pointer in the general case. If it has static duration that is true, but
if it has automatic duration (i.e. a pointer variable declared in a
function that is not specified as static) it would be a pure fluke if it
happened to be a null pointer.

It is true that a null pointer does not point anywhere. It is also the
only pointer value that you are guaranteed to be able to convert to any
other pointer value. Null pointers are normally either generated by you
explicitly using them in the source or on a library routine that returns
a pointer failing.
> A pointer to void is a pointer
of some unknown type assigned an address in memory.

A variable of type void* might point to something, or on the other hand
it could be uninitialised or a null pointer. The pointer itself has no
type information so it could point at any type of object (not a
function) and it is up to the programmer to keep track of what type it
points to.
 
F

Flash Gordon

Abhishek wrote:

Please don't top post. Your reply belongs under the text you are
replying to after snipping anything not relevant to your reply. I've
corrected it this time.

In general casts are a bad thing. They tell the compiler you know what
you are doing even if you don't. So those who do not have a thorough
understanding should not use them until they know *why* they are needed
in a given situation. My experience is that I have seen more casts to
shut the compiler up without solving the underlying problem (and leaving
in significant errors without the compiler complaining as a result) then
I have seen casts that were required. They also add visual clutter which
IMHO makes it harder to read.

Please snip peoples signatures (the bit after the -- normally) unless
you are commenting on them.
Thank you all for that wonderful explanation.
So, whats the difference between a null pointer and a pointer which is
pointing to void?
Are these same?

What is the difference between an integer variable and the value 0?

The null pointer is a specific pointer value that does not point
anywhere. You can have null pointers of any pointer type and they always
compare equal to each other when converted to a common pointer type.
Null pointers are also returned by various library functions to indicate
failure.

A pointer to void is a specific type of pointer (just as long is a
specific type of integer). Any pointer to object type (not a pointer to
a function) can be converted to void* and back safely. Converting
to/from void* to other object pointer types does not require a cast. So
pointers to void are a generic pointer type.
 
L

Lucien Kennedy-Lamb

Abhishek said:
So, whats the difference between a null pointer and a pointer which is
pointing to void?
Are these same?

You require a proper explanation of what the terms 'null' and 'void'
actually mean in C. Their meanings differ from the standard English
sense (just to confuse everyone).


Null...

In the English language "null" means insignificant, missing or
amounting to nothing. It can also mean zero. In fact the German
language for number zero is "null".

http://german.about.com/library/anfang/blanfang07.htm

Don't let that confuse you.

In C terms a null pointer is a pointer that doesn't point to any
variable, structure or function *anywhere*. It's like having a finger
that is designed to point to a spot on a map. Point to anywhere on the
map and it will have some well defined coordinate (address), but if you
haven't decided where to point that finger quite yet... point that
finger upwards into space (null).

The null value for pointers is only useful for setting pointers that
haven't been initialised to a *real* address.

Null pointers *must* be assigned using the NULL macro (defined by
<stdio.h>). The reason is that, while most of the time NULL is defined
as 0, it may not be on every platform.

char *string = NULL; /* I'm not pointing to anything useful yet */

CALL FOR COMMENT HERE: I've never seen a compiler *not* use 0 as NULL,
so who has? Who can list an example where this is not the case? I've
seen so much code that relies on the NULL == 0 assumption.

Use of a null pointer?

Any pointer can be assigned the NULL value. I can be a char, int, long
or any structure or union pointer.

void PrintMyString(char *string)
{
if (string != NULL) /* Check if this is a real address of a
possible string */
printf("This is the string: %s", string);
}

and my favourite is:

void ProcessTaxReturn(struct TAX_RETURN *p_tax_return)
{
if (p_tax_return != NULL) /* Has a valid tax return structure been
received? */
{
SendLargeTaxBill(p_tax_return);
}
}

I've been trying for years to send a null tax return, but it's never
worked. :)


Void...

In the English language "void" means empty, useless or a vacuum.

In C it has quite a different meaning. My best explanation is a type
of zero length data.

Consider:

void DoSomthing(void);

The compiler knows what there is no return and no arguments to this
function.

void*

What does this mean? It's a pointer like any other pointer. It holds
the address of a memory location.

It simply means that "I've got the address of *something*, but I don't
know what it is".

void *pointers are generally used between software components that
expose an interface where the type of data is unknown.

Consider

void *malloc(size_t size);

This standard C library function returns a void * as it has no idea how
this memory block is to be used for (something addressed in C++ with
the new operator).

void* pointers is a convenient way of passing around data pointers when
types con't be conveyed. Use them sparingly because real types (and
typedefs) should be used whenever possible.

I hope this goes some way to explaining how void and null should be
used.

Lucien Kennedy-Lamb
 
P

pete

Lucien Kennedy-Lamb wrote:
Null pointers *must* be assigned using the NULL macro (defined by
<stdio.h>). The reason is that,
while most of the time NULL is defined
as 0, it may not be on every platform.

char *string = NULL; /* I'm not pointing to anything useful yet */

There's nothing wrong with:
char *string = 0;
It means exactly the same thing thing as
char *string = NULL;
no matter how NULL is defined.
 
K

Keith Thompson

Please don't change the subject header when posting a followup without
a very good reason, and please don't use an all-caps subject (it looks
like spam).

Lucien Kennedy-Lamb said:
The null value for pointers is only useful for setting pointers that
haven't been initialised to a *real* address.

It's not really about initialization. It's perfectly legitimate to
assign the value NULL to a pointer that currently points to some
object.
Null pointers *must* be assigned using the NULL macro (defined by
<stdio.h>). The reason is that, while most of the time NULL is defined
as 0, it may not be on every platform.

char *string = NULL; /* I'm not pointing to anything useful yet */

CALL FOR COMMENT HERE: I've never seen a compiler *not* use 0 as NULL,
so who has? Who can list an example where this is not the case? I've
seen so much code that relies on the NULL == 0 assumption.

That's not quite correct.

What code have you seen that relies on NULL == 0? Since a literal 0
is a null pointer constant, they're guaranteed to be equal, but a null
pointer *value* isn't necessarily represented as all-bits-zero. I use
systems where the NULL macro is defined as 0, and others where it's
defined as ((void*)0). This shouldn't make any difference for
well-written code.

Please read section 5 of the C FAQ, available at www.c-faq.com.
Void...

In the English language "void" means empty, useless or a vacuum.

In C it has quite a different meaning. My best explanation is a type
of zero length data.

It would be better to say it's a type that doesn't have a size. More
precisely, it's an incomplete type that cannot be completed.

You can't have an object of type void. You can have a
pointer-to-void, but you can't dereference it unless you first convert
it to some pointer-to-object type.
Consider:

void DoSomthing(void);

The two "void"s here mean different things. The first means that the
function doesn't return a value (or that it returns type "void"). The
second means that the function doesn't take any arguments; it doesn't
refer to the void type. The use in "void*" is arguably a third
distinct meaning. (It's not *quite* as bad as "static").

See section 4 of the C FAQ.
 
J

Jordan Abel

Null pointers *must* be assigned using the NULL macro (defined by
<stdio.h>). The reason is that, while most of the time NULL is defined
as 0, it may not be on every platform.

not quite. NULL's representation may not be all bits zero, but a
constant 0 assigned to a pointer must be a null pointer.
char *string = NULL; /* I'm not pointing to anything useful yet */

CALL FOR COMMENT HERE: I've never seen a compiler *not* use 0 as NULL,
so who has? Who can list an example where this is not the case? I've
seen so much code that relies on the NULL == 0 assumption.

Your interpretation of the standard is incorrect.
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top