473,398 Members | 2,088 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

void *

Hello,

I want to adapt my linked list implementation to hold any data types. As I
understand it's a good place to use 'void *'. Here's what I've done:

struct list_node
{
void *data;
struct list_node *next;
};

typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */
n->next = *head;
...
}

Does such a use of 'void *' guarantee that I can supply various data types,
i.e. ints. long. chars and so forth?
Thanks in advance.

--
Best regards, Roman
Jun 28 '07 #1
35 2212
TJ
On Jun 29, 2:05 am, "Roman Mashak" <m...@tusur.ruwrote:
Hello,

I want to adapt my linked list implementation to hold any data types. As I
understand it's a good place to use 'void *'. Here's what I've done:

struct list_node
{
void *data;
struct list_node *next;

};

typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */
n->next = *head;
...

}

Does such a use of 'void *' guarantee that I can supply various data types,
i.e. ints. long. chars and so forth?
Thanks in advance.

--
Best regards, Roman
IIRC, packing ints/longs/chars into pointers is not standards
conforming code. You can put pointers to data objects into your list
struct. Pointers to functions are also not storeable in void*.

Cheers,

TJ

Jun 28 '07 #2
On Thu, 28 Jun 2007 11:05:42 -0700, "Roman Mashak" <mr*@tusur.ru>
wrote:
>Hello,

I want to adapt my linked list implementation to hold any data types. As I
understand it's a good place to use 'void *'. Here's what I've done:

struct list_node
{
void *data;
struct list_node *next;
};
It would probably help if your structure had a member which identified
the real type of whatever data pointed to.
>
typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */
n->data is a void*. data is a void*. What do you think the cast
accomplishes?
n->next = *head;
You need to set *head to n.
...
}

Does such a use of 'void *' guarantee that I can supply various data types,
i.e. ints. long. chars and so forth?
No, it guarantees that you can supply pointers to the various data
types (only object pointers, not function pointers).
Remove del for email
Jun 28 '07 #3

"Barry Schwarz" <sc******@doezl.netwrote in message
news:2c********************************@4ax.com...
>>
struct list_node
{
void *data;
struct list_node *next;
};

It would probably help if your structure had a member which identified
the real type of whatever data pointed to.
But the structure can't have members for all possible types. And I expected
'void *' is to hold _pointers_ on the objects of various types (perhaps I
wasn't very clear in my original post), i.e. I could you something like
this:

int main(void)
{
node *p = NULL;

list_add_head(&p, (int *)100);
list_add_head(&p, (char *)'X');
...
return 0;
}

That was my understanding of 'void *' concept.
>
>>
typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */

n->data is a void*. data is a void*. What do you think the cast
accomplishes?
So, n->data = data is enough?
> n->next = *head;

You need to set *head to n.
> ...
}

Does such a use of 'void *' guarantee that I can supply various data
types,
i.e. ints. long. chars and so forth?

No, it guarantees that you can supply pointers to the various data
types (only object pointers, not function pointers).
--
Best regards, Roman
Jun 28 '07 #4
Roman Mashak wrote, On 28/06/07 21:35:
"Barry Schwarz" <sc******@doezl.netwrote in message
news:2c********************************@4ax.com...
>>struct list_node
{
void *data;
struct list_node *next;
};
It would probably help if your structure had a member which identified
the real type of whatever data pointed to.

But the structure can't have members for all possible types. And I expected
'void *' is to hold _pointers_ on the objects of various types (perhaps I
wasn't very clear in my original post), i.e. I could you something like
this:

int main(void)
{
node *p = NULL;

list_add_head(&p, (int *)100);
This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
list_add_head(&p, (char *)'X');
This is converting another int (not char), this time to a pointer to
char. Same problem.
...
return 0;
}

That was my understanding of 'void *' concept.
The concept of void* is what you described in your text, *not* what you
show in your code. I.e.

void *p;
int i;
char c;
p = &i;
p = &c;

Note that it does *not* require a cast.

In fact at your level the first thing you should assume when you appear
to need a cast is that you have done something wrong and a cast is *not*
the solution. If it appears that you have not done anything wrong then
your next assumption should be that you have completely misunderstood
something fundamental and done something very wrong.

There are a few places where casts are required, but not in general
where you would expect.
>>typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */
n->data is a void*. data is a void*. What do you think the cast
accomplishes?

So, n->data = data is enough?
When two variables are of the same type of *course* it is.

Personally I don't think you understand the concept of pointers yet, so
you need to read the sections of your text book and the comp.lang.c FAQ
that refer to pointers. The comp.lang.c FAQ is available at
http://c-faq.com/
--
Flash Gordon
Jun 28 '07 #5
On Jun 28, 1:35 pm, "Roman Mashak" <m...@tusur.ruwrote:
"Barry Schwarz" <schwa...@doezl.netwrote in message

news:2c********************************@4ax.com...
>struct list_node
{
void *data;
struct list_node *next;
};
It would probably help if your structure had a member which identified
the real type of whatever data pointed to.

But the structure can't have members for all possible types. And I expected
'void *' is to hold _pointers_ on the objects of various types (perhaps I
wasn't very clear in my original post), ...
He meant:

struct list_node
{
void *data;
unsigned datatype; /* 0 = invalid, 1=char, 2=short, 3=...*/
struct list_node *next;
};

[snip]

Jun 28 '07 #6
Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
[...]

Quibble: Well, yes, it is guaranteed. The result is
implementation-defined, and can even be a trap representation.
In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 28 '07 #7
Roman Mashak said:

<snip>
>
And I
expected 'void *' is to hold _pointers_ on the objects of various
types (perhaps I wasn't very clear in my original post), i.e. I could
you something like this:

int main(void)
{
node *p = NULL;

list_add_head(&p, (int *)100);
No. That's just silly.
list_add_head(&p, (char *)'X');
...
return 0;
}

That was my understanding of 'void *' concept.
Your understanding is going nowhere, I'm afraid - but that can be fixed,
if only you can put down your void * and your cast and your &, and
instead tell us what you're trying to do.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 28 '07 #8

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:5v*********************@bt.com...
>>
That was my understanding of 'void *' concept.

Your understanding is going nowhere, I'm afraid - but that can be fixed,
if only you can put down your void * and your cast and your &, and
instead tell us what you're trying to do.
I want to hold pointers on to objects of various types in the structurre
member, named 'data'. I declared it as 'void *' and faced various problems
:(

--
Best regards, Roman
Jun 28 '07 #9

"Flash Gordon" <sp**@flash-gordon.me.ukwrote in message
news:lf************@news.flash-gordon.me.uk...
> list_add_head(&p, (int *)100);

This is *not* getting a pointer to an int, it is coercing an int in to an
int pointer. There is no guarantee that all int values can be converted to
pointers.
Agree, I was mistaken. Here's the changed version:

struct list_node
{
void *data;
struct list_node *next;
};

node* list_add_tail(node **head, void *data)
{
node *current = *head;
node *n;

n = malloc(sizeof *n);
if (n == NULL)
return NULL;

n->data = data;
n->next = NULL;

/* special case for length 0 */
if (current == NULL) {
*head = n;
} else {
/* locate the last node */
while (current->next != NULL) {
current = current->next;
}
current->next = n;
}

return n;
}

int main(void)
{
int i, j;
node *p = NULL;
...
i = 10; j = 20;
list_add_tail(&p, &i);
list_add_tail(&p, &j);
}

Now p->data holds the pointers of 'i' and 'j', and this matches the concept
of generic pointer 'void *'. But how to print the _value_ of 'data'? This
code is not compilable:

while (p != NULL) {
printf("Node %p\nNext %p\nData %d\n\n", (void *)p, (void *)p->next,
*(p->data));
p = p->next;
}

warning: dereferencing 'void *' pointer
error: invalid use of void expression

And I think I used (void *) casting here properly, because otherwise
compiler generates warning: void format, node arg (arg 2).

I'm keen to understand the pointers hell.

[skip]
>
The concept of void* is what you described in your text, *not* what you
show in your code. I.e.

void *p;
int i;
char c;
p = &i;
p = &c;

Note that it does *not* require a cast.

In fact at your level the first thing you should assume when you appear to
need a cast is that you have done something wrong and a cast is *not* the
solution. If it appears that you have not done anything wrong then your
next assumption should be that you have completely misunderstood something
fundamental and done something very wrong.

There are a few places where casts are required, but not in general where
you would expect.
--
Best regards, Roman
Jun 28 '07 #10
Roman Mashak said:
>
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:5v*********************@bt.com...
>>>
That was my understanding of 'void *' concept.

Your understanding is going nowhere, I'm afraid - but that can be
fixed, if only you can put down your void * and your cast and your &,
and instead tell us what you're trying to do.

I want to hold pointers on to objects of various types in the
structurre member, named 'data'. I declared it as 'void *' and faced
various problems
:(
That still isn't very clear. What real world problem are you trying to
solve? Here's my guess at what you want:

A container that can store any kind of object, such that you can process
the object (create it, initialise it, copy it, compare it, change it,
print it, etc) without the container knowing anything about its type.

Is that right?

If so, I can certainly help you. But at present, I still don't know what
you want.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 28 '07 #11
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Re*********************@bt.com...
That still isn't very clear. What real world problem are you trying to
solve? Here's my guess at what you want:

A container that can store any kind of object, such that you can process
the object (create it, initialise it, copy it, compare it, change it,
print it, etc) without the container knowing anything about its type.

Is that right?
I'm implementing single linked list, with such traditional node's structure:

struct list_node
{
void *data;
struct list_node *next;
};

I want to store in my LL objects of different types: ints, longs, chars etc.
My assumption was that declaring a structure member as 'void *' may help me
(please also check my reply to Flash Gordon).

--
Best regards, Roman
Jun 28 '07 #12
Roman Mashak said:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Re*********************@bt.com...
>That still isn't very clear. What real world problem are you trying
to solve? Here's my guess at what you want:

A container that can store any kind of object, such that you can
process the object (create it, initialise it, copy it, compare it,
change it, print it, etc) without the container knowing anything
about its type.

Is that right?

I'm implementing single linked list,
Aha!
I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me (please also check my reply to Flash Gordon).
If you want to *store* objects in the linked list, as you say, then
you'll need to know how big they are so that you can copy them.
Otherwise you're not storing, just pointing.

Simple objects are easy to copy:

#include <stdlib.h>

void *objdup(const void *old, size_t size)
{
void *new = malloc(size);
if(new != NULL)
{
memcpy(new, old, size);
}
return new;
}

but some objects are more complicated than that - strings, structs with
pointers in them, etc. If you're only dealing with simple objects,
either make each list homogenous (i.e. only deals with objects of one
particular size) and keep a size in the header, or if you need
heterogenous lists, store a size and a type indicator in each node.

If you need to be able to store complicated objects - strings, or
anything with a pointer in it - you might want to look at callback
functions to do your copying (and other object-related activity) for
you.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 28 '07 #13
Richard Heathfield <rj*@see.sig.invalidwrites:
Roman Mashak said:

<snip>
>>
And I
expected 'void *' is to hold _pointers_ on the objects of various
types (perhaps I wasn't very clear in my original post), i.e. I could
you something like this:

int main(void)
{
node *p = NULL;

list_add_head(&p, (int *)100);

No. That's just silly.
> list_add_head(&p, (char *)'X');
...
return 0;
}

That was my understanding of 'void *' concept.

Your understanding is going nowhere, I'm afraid - but that can be fixed,
if only you can put down your void * and your cast and your &, and
instead tell us what you're trying to do.
It seems fairly obvious to me.

A single set of code to store references to data elements of various types.
Jun 28 '07 #14
Richard Heathfield <rj*@see.sig.invalidwrites:
Roman Mashak said:
>"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Re*********************@bt.com...
>>That still isn't very clear. What real world problem are you trying
to solve? Here's my guess at what you want:

A container that can store any kind of object, such that you can
process the object (create it, initialise it, copy it, compare it,
change it, print it, etc) without the container knowing anything
about its type.

Is that right?

I'm implementing single linked list,

Aha!
>I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me (please also check my reply to Flash Gordon).

If you want to *store* objects in the linked list, as you say, then
you'll need to know how big they are so that you can copy them.
Otherwise you're not storing, just pointing.
He was pointing and he specifically said that above. Yes, he got his
language wrong in the last reply - but you prompted him into that.

Why do you always feel the need to embellish and obfuscate?
Here:

,----
| I want to hold pointers on to objects of various types in the structurre
| member, named 'data'. I declared it as 'void *' and faced various problems
| :(
`---

How is that anyway unclear?
Jun 28 '07 #15
If you need to be able to store complicated objects - strings, or
anything with a pointer in it - you might want to look at callback
functions to do your copying (and other object-related activity) for
you.
He is write. What you want can be achieved with callback functions. In
fact, I've implemented very similar linked list storing void* and
taking in callbacks for data specific operations like:

int list_display(node *head, void (*disp)(void *data)) {
if (disp) {
(*disp)(head->data);
}
else {
printf("data %p\n", head->data);
}
}

similarly, getting element, freeing can take user specific callbacks.

Regards,
Manish
(http://manishtomar.blogspot.com)

Jun 28 '07 #16
On Thu, 28 Jun 2007 13:35:06 -0700, "Roman Mashak" <mr*@tusur.ru>
wrote:
>
"Barry Schwarz" <sc******@doezl.netwrote in message
news:2c********************************@4ax.com.. .
>>>
struct list_node
{
void *data;
struct list_node *next;
};

It would probably help if your structure had a member which identified
the real type of whatever data pointed to.

But the structure can't have members for all possible types. And I expected
No, but it could have an enum member which had values defined for
e_char, e_short, e_int, e_long, e_float, e_double, e_struct_1, etc so
that any code that needed to manipulate whatever data pointed to could
determine the real type.
>'void *' is to hold _pointers_ on the objects of various types (perhaps I
wasn't very clear in my original post), i.e. I could you something like
this:

int main(void)
{
node *p = NULL;

list_add_head(&p, (int *)100);
list_add_head(&p, (char *)'X');
I hope not. Casting integer literals to pointers is implementation
defined at best. If an int must be aligned on a four-byte boundary,
you could never do
list_add_head(&p, (int*)5);

You really don't want data to contain the value of interest; you want
it to point to an object set to that value.
...
return 0;
}

That was my understanding of 'void *' concept.
A void* can point to any type of object. It cannot contain an
arbitrary value of any type. On my system, sizeof(void*) is 4 and
sizeof(double) is 8. I cannot stuff a double into a void* but I can
assign the address of a double to a void*. (It gets even worse if you
intend your structure to be able to point to other structures or
arrays.)
>
>>
>>>
typedef struct list_node node;

node* list_add_head(node **head, void *data)
{
node *n= malloc(sizeof *n);
/* check if n==NULL ...*/

n->data = (void *)data; /* is that correct use? */

n->data is a void*. data is a void*. What do you think the cast
accomplishes?

So, n->data = data is enough?
Yes. Since both types are the same, a cast is never needed.
Furthermore, there is an implied conversion in either direction
between any unqualified type of object pointer and void* so if either
operand is a void* a cast is not needed. (See your statement that
calls malloc for an example of this.)
>
>> n->next = *head;

You need to set *head to n.
>> ...
}

Does such a use of 'void *' guarantee that I can supply various data
types,
i.e. ints. long. chars and so forth?

No, it guarantees that you can supply pointers to the various data
types (only object pointers, not function pointers).

Remove del for email
Jun 28 '07 #17
Richard <rg****@gmail.comwrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
Roman Mashak said:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Re*********************@bt.com...
That still isn't very clear. What real world problem are you trying
to solve? Here's my guess at what you want:

A container that can store any kind of object, such that you can
process the object (create it, initialise it, copy it, compare it,
change it, print it, etc) without the container knowing anything
about its type.

Is that right?

I'm implementing single linked list,
Aha!
I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me (please also check my reply to Flash Gordon).
If you want to *store* objects in the linked list, as you say, then
you'll need to know how big they are so that you can copy them.
Otherwise you're not storing, just pointing.
He was pointing and he specifically said that above. Yes, he got his
language wrong in the last reply - but you prompted him into that.
That's still absolutely unclear. One of the code snippets Roman
posted upthread on the use of the function was:

| int main(void)
| {
| node *p = NULL;
|
| list_add_head(&p, (int *)100);
| list_add_head(&p, (char *)'X');
| ...
| return 0;
| }

This makes it look as if he tries to store the value of an
object (of arbitrary type) in a void pointer and not just
pointers to objects. And that's what he then repeated in
words in his last post.

Or, if his other post is to believed,

| I want to hold pointers on to objects of various types in the structurre
| member, named 'data'. I declared it as 'void *' and faced various problems

then he might be assuming wrongly that e.g. "(int *) 100"
would result in a pointer to somewhere where the number 100
would be stored. So Roman may be believing that he want's
to store pointers, but what he's actually doing is storing
is a pointer that is the result of a non-portable conversion
data he won't be able to use reasonably. My bet at the moment
is that he actually wants to store values and doesn't realize
that casting to a void pointer and storing the result won't
do what he expects it to do. But he's the only person that
can tell us.
Why do you always feel the need to embellish and obfuscate?
Richard Heathfield is just trying to figure out what Roman
is up to and what exactly his mis-conceptions are. And what
you call "embellish and obfuscate" is actually trying to
elicit a clear answer about what Roman really wants to do.

And, of course, there also still remains the problem of how
to get the data out of the list again when it's not stored
what the original type was, independent of the question if
values or pointers are to be stored in the list elements.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jun 28 '07 #18
Richard said:

<snip>
>
Why do you always feel the need to embellish and obfuscate?
I'm just trying to find out what he actually wants to do, which is still
far from clear (although clearer than it was).

If you really want to help him, why not answer his question yourself?
Here:

,----
| I want to hold pointers on to objects of various types in the
| structurre member, named 'data'. I declared it as 'void *' and faced
| various problems
| :(
`---

How is that anyway unclear?
If you think it's clear, answer it yourself.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 28 '07 #19
Roman Mashak wrote:
>
.... snip ...
>
I'm implementing single linked list, with such traditional node's
structure:

struct list_node
{
void *data;
struct list_node *next;
};

I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me
That's fine so far, but whatever function receives the void* MUST
know what the actual type is, IF it is going to dereference it. So
you have code something like:

whatever foo(void *p, etc) {
T pt = p;

/* process based on pt */
return something;
}

Notice the lack of casts.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 28 '07 #20
In article <87************@gmail.com>, Richard <rg****@gmail.comwrote:
>Dicky Heathfield <rj*@see.sig.invalidwrites:
A bunch of his usual junk.
....
>He was pointing and he specifically said that above. Yes, he got his
language wrong in the last reply - but you prompted him into that.

Why do you always feel the need to embellish and obfuscate?
Do you really have to ask this?

Jun 28 '07 #21

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:5L******************************@bt.com...
>I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me (please also check my reply to Flash Gordon).
I apologize, gentlemen, but I misled you. I expressed myself with ambiguity
and need to correct now. What I really want is 'void *data' member to store
_pointers_ to objects of various types (say, 'int', 'long', 'char' in the
first place), I confused two terms 'object' and 'pointer to object'.

Now I realized that casting is a wrong way and better solution would be to
have a callback function with a parameter indicating the real type,
somewehat like this:

enum e_types {
e_int,
e_long,
e_char
};
typedef e_types e_types;

node* list_add_head(node **head, int(func *)(void *data, e_types t))
{
....
}

Where (func *) is to handle the types properly. Am I on right path?
>
If you want to *store* objects in the linked list, as you say, then
you'll need to know how big they are so that you can copy them.
Otherwise you're not storing, just pointing.

Simple objects are easy to copy:
--
Best regards, Roman
Jun 29 '07 #22
Roman Mashak said:
>
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:5L******************************@bt.com...
>>I want to store in my LL objects of different types: ints, longs,
chars etc. My assumption was that declaring a structure member as
'void *' may help me (please also check my reply to Flash Gordon).

I apologize, gentlemen, but I misled you. I expressed myself with
ambiguity and need to correct now. What I really want is 'void *data'
member to store
_pointers_ to objects of various types (say, 'int', 'long', 'char' in
the first place), I confused two terms 'object' and 'pointer to
object'.
In which case this is (a) easy and (b) probably pointless. void * can
point to any object type without any problem:

#include <stdlib.h>

struct llnode
{
void *data;
struct llnode *next;
};

/* llnode_add - adds a new node to a linked list. A pointer to the
existing head of the list is passed in (or NULL if the list is
currently empty). The new node becomes the new head of the list,
and a pointer to it is returned. (If the storage can't be
allocated, NULL is returned.)
*/
struct llnode *llnode_add(struct llnode *head, void *data)
{
struct llnode *new = malloc(sizeof *new);
if(new != NULL)
{
new->data = data;
new->next = head;
}
return new;
}

But this will only point to data. It won't know what kind of data it
points to, how big it is, how to process it, or anything like that. And
it won't "own" the data, so you have to do that, and you have to know
when to remove items from the list as and when they go out of scope
(and which items they are). This is a recipe for a million headaches.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 29 '07 #23

"Keith Thompson" <ks***@mib.orgha scritto nel messaggio news:ln************@nuthaus.mib.org...
Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
>This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
[...]

Quibble: Well, yes, it is guaranteed. The result is
implementation-defined, and can even be a trap representation.
In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).
"Almost"? Ever heard of the pidgeonhole principle?
Jun 29 '07 #24
Army1987 wrote:
>
"Keith Thompson" <ks***@mib.orgha scritto nel messaggio news:ln************@nuthaus.mib.org...
>Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
>>This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
[...]

Quibble: Well, yes, it is guaranteed. The result is
implementation-defined, and can even be a trap representation.
In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).

"Almost"? Ever heard of the pidgeonhole principle?
Isn't the implementation allowed to raise a signal on the conversion? In
which case, it could be that /some/ integers won't convert at all, and hence
don't convert to values equal to those from some other integer which
does convert.

--
Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

Jun 29 '07 #25
In article <f6**********@murdoch.hpl.hp.com>,
Chris Dollin <ch**********@hp.comwrote:
>Army1987 wrote:
>>
"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
>>In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).

"Almost"? Ever heard of the pidgeonhole principle?

Isn't the implementation allowed to raise a signal on the conversion? In
which case, it could be that /some/ integers won't convert at all, and hence
don't convert to values equal to those from some other integer which
does convert.
A sufficiently perverse implementation could even generate a *different*
signal for every non-convertable pointer, so that not even the best
nitpicker could claim that it's producing the same result for two
different pointers.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca

So long, and thanks for all the haiku.
--Richard Heathfield in comp.lang.c
Jun 29 '07 #26
In article <f6**********@rumours.uwaterloo.ca>,
Dave Vandervies <dj******@csclub.uwaterloo.cawrote:
>In article <f6**********@murdoch.hpl.hp.com>,
Chris Dollin <ch**********@hp.comwrote:
>>Army1987 wrote:
>>"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
>>>In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).
>>"Almost"? Ever heard of the pidgeonhole principle?
>>Isn't the implementation allowed to raise a signal on the conversion? In
which case, it could be that /some/ integers won't convert at all, and hence
don't convert to values equal to those from some other integer which
does convert.
>A sufficiently perverse implementation could even generate a *different*
signal for every non-convertable pointer, so that not even the best
nitpicker could claim that it's producing the same result for two
different pointers.
signal takes an int as its signal number, so if the integer type
is wider than sizeof(int) + sizeof(void*) you wouldn't be
able to generate different signal for each one.
--
All is vanity. -- Ecclesiastes
Jun 29 '07 #27
"Army1987" <pl********@for.itwrites:
"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
>Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
>>This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
[...]

Quibble: Well, yes, it is guaranteed. The result is
implementation-defined, and can even be a trap representation.
In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).

"Almost"? Ever heard of the pidgeonhole principle?
Yes, "almost". Think about padding bits. I carefully said "integer
values", not "integer representations".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 29 '07 #28
Chris Dollin <ch**********@hp.comwrites:
Army1987 wrote:
>"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
>>Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
This is *not* getting a pointer to an int, it is coercing an int in to
an int pointer. There is no guarantee that all int values can be
converted to pointers.
[...]

Quibble: Well, yes, it is guaranteed. The result is
implementation-defined, and can even be a trap representation.
In particular, different integer values may convert to the same
pointer value (and almost certainly will if the integer type is
bigger than the pointer type).

"Almost"? Ever heard of the pidgeonhole principle?

Isn't the implementation allowed to raise a signal on the
conversion? In which case, it could be that /some/ integers won't
convert at all, and hence don't convert to values equal to those
from some other integer which does convert.
Surprisingly, no, an integer-to-pointer conversion cannot raise a
signal. An integer-to-integer-conversion either yields an
implementation-defined result or raises an implementation-defined
signal if the target type is signed and the result can't be
represented; the permission to raise a signal is new in C99. There is
no such permission for integer-to-pointer conversions; they merely
yield an implementation-defined result (except in the special case of
null pointer constants). Attempting to *use* that result can invoke
undefined behavior, though, which of course can include raising a
signal.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 29 '07 #29
No, but it could have an enum member which had values defined for
e_char, e_short, e_int, e_long, e_float, e_double, e_struct_1, etc so
that any code that needed to manipulate whatever data pointed to could
determine the real type.
I personally don't think using an enum to stores types is a good idea
mainly because, the implementation is doing more than it should. It
should not involve in knowing the type of data and deciding how to
handle it. Also, it would become difficult to extend this modal for
user specific data using structures. Taking standard lib qsort as
example, I would recommend callback without type as possible solution.

Regards,
Manish
(http://manishtomar.blogspot.com)

Jul 2 '07 #30
Manish Tomar wrote:
printf("data %p\n", head->data);
My preferred way of writing that, is:

puts(head -data);

--
pete
Jul 4 '07 #31
pete <pf*****@mindspring.comwrites:
Manish Tomar wrote:
> printf("data %p\n", head->data);

My preferred way of writing that, is:

puts(head -data);
Your statement does something completely different from the printf.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 4 '07 #32
On Wed, 04 Jul 2007 03:36:15 GMT, pete <pf*****@mindspring.comwrote:
>Manish Tomar wrote:
> printf("data %p\n", head->data);

My preferred way of writing that, is:

puts(head -data);
But they don't do the same thing.

The printf version writes the address contained in the
pointer.

The puts version writes the string the pointer points to.
Remove del for email
Jul 4 '07 #33
Keith Thompson wrote:
>
pete <pf*****@mindspring.comwrites:
Manish Tomar wrote:
printf("data %p\n", head->data);
My preferred way of writing that, is:

puts(head -data);

Your statement does something completely different from the printf.
I take it all back.

--
pete
Jul 4 '07 #34
Richard Heathfield <rj*@see.sig.invalidwrites:
Richard said:

<snip>
>>
Why do you always feel the need to embellish and obfuscate?

I'm just trying to find out what he actually wants to do, which is still
far from clear (although clearer than it was).

If you really want to help him, why not answer his question yourself?
>Here:

,----
| I want to hold pointers on to objects of various types in the
| structurre member, named 'data'. I declared it as 'void *' and faced
| various problems
| :(
`---

How is that anyway unclear?

If you think it's clear, answer it yourself.
It is incredibly clear to anyone who allowed themselves to think like a
human.

What else could

"I want to hold pointers on to objects of various types"

compile too in your thinking? It is clear as day, especially in the
light of the demo code he posted.

I hope to hell you are not a teacher of any kind.
Jul 4 '07 #35
[Much context snippage. What I've left is my actual question ("why not
answer his question yourself?") and the fresh text "Richard" added in
his so-called reply.]

Richard said:
Richard Heathfield <rj*@see.sig.invalidwrites:
<snip>
>If you really want to help him, why not answer his question yourself?
<snip>
It is incredibly clear to anyone who allowed themselves to think like
a human.

What else could

"I want to hold pointers on to objects of various types"

compile too in your thinking? It is clear as day, especially in the
light of the demo code he posted.

I hope to hell you are not a teacher of any kind.

So there we have it. "Richard" is not interested in answering the
original question and helping the original questioner. If he were, he
would have provided an answer. Instead, he continues to carp. Well,
that's up to him, but he has damaged his credibility by claiming to be
interested in helping the OP and yet passing up this golden opportunity
to demonstrate the fact by actually doing so.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 4 '07 #36

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

192
by: Kwan Ting | last post by:
The_Sage, I see you've gotten yourself a twin asking for program in comp.lang.c++ . http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&th=45cd1b289c71c33c&rnum=1 If you the oh so mighty...
15
by: Stig Brautaset | last post by:
Hi group, I'm playing with a little generic linked list/stack library, and have a little problem with the interface of the pop() function. If I used a struct like this it would be simple: ...
188
by: infobahn | last post by:
printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
7
by: sunglo | last post by:
My doubt comes from trying to understand how thread return values work (I know, it's off topic here), and I'm wondering about the meaning of the "void **" parameter that pthread_join expects (I...
9
by: Juggernaut | last post by:
I am trying to create a p_thread pthread_create(&threads, &attr, Teste, (void *)var); where var is a char variable. But this doesnt't work, I get this message: test.c:58: warning: cast to pointer...
5
by: Stijn van Dongen | last post by:
A question about void*. I have a hash library where the hash create function accepts functions unsigned (*hash)(const void *a) int (*cmp) (const void *a, const void *b) The insert function...
56
by: maadhuu | last post by:
hello, this is a piece of code ,which is giving an error. #include<stdio.h> int main() { int a =10; void *p = &a; printf("%d ", *p ); //error....why should it //be an error ?can't the...
27
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in...
18
by: Giannis Papadopoulos | last post by:
According to the standard (ISO C99 draft WG14/N1124), void is the incomplete type that cannot be completed and comprises the empty set of values. Since it declares the absense of a value can it be...
4
by: brianhray | last post by:
Hello: I am writing a C interface and was curious how/why a void* can be used as a reference parameter. //////////////////////////////////////////////////////////// // WORKS: // Client1.h...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.