Minimum size of void *

K

Keith Thompson

Flash Gordon said:
Keith Thompson wrote, On 05/09/07 21:33:
Keith Thompson said:
[...]
Under AIX a function pointer is two pointers:
1) The pointer to the code
2) The pointer to the global section of the function, i.e. the
value that will be loaded in a dedicated register for accessing
the global variables.

When you take the address of a function, the compiler generates a
structure with those two pointers, and gives you a pointer to THAT
structure, specially if you write
sizeof(f*)
instead of sizeof(f);
You are mistaken. [snip]
What do you mean by 'sizeof(f*)' and 'sizeof(f)'? What is 'f'?
Sorry, I missed the declaration of f in the previous article:
typedef int f(void);
sizeof(f*) is, of course, a constraint violation.

Surely you mean sizeof(f) is a constraint violation because it is
taking the size of a function type, whereas sizeof(f*) is legal
because i is taking the size of a pointer to a function.

No, I meant what I said. I was completely wrong, but I meant it.

Seriously, you're quite correct; thanks for catching my error.
 
C

CBFalconer

Rob said:
I'm working on a hashtable-based dictionary implementation in C,
and it uses void pointers for data storage, naturally. However,
since one of the data types I will be using it for is unsigned
long -> unsigned long, I figure it'd be a better idea to just
cast the unsigned longs I'm inserted into the void pointer slots
to avoid mallocs, frees, and unnecessary deferencing. On my
machine, this is fine; void * are 32 bits. Is this necessarily
the case on all machines as per the C standard? I poured over
the C89 specs and couldn't find anything on pointer size; I
assume that it's always native word size, which would require me
to think up a different solution.

Before you get all tied up in a specialized hashtable, try my
hashlib library and work out the other details. It is available,
GPL licensed and written in standard C, with several example
applications, at:

<http://cbfalconer.home.att.net/download/>

Then you can evaluate whether a specialized table really gives you
any discernable performance improvement.
 
R

Richard Bos

As any pointer type can be converted to void * and back to the
same pointer type and have the results compare equal to the
original, it follows that void * must be big enough to hold the
largest pointer.

Not necessarily; at least, not necessarily in the way the OP wants it.
It is quite possible for void * (and by necessity, char *) to be lean
pointers containing nothing but the value, and all others to be fat
pointers, containing the pointer value plus some information about the
type and extent of the object pointed at. If the pointer value itself is
the same size in all cases, this would make the size of a void * (or
char *) smaller than that of other object pointers.
Conversion through void * would then lose that special information, but
the implementation could work around that; all that is required is that
the resulting pointer compares equal to the original, not that it is
bit-by-bit identical. You'd need internal special casing for dealing
with int pointers whose extra bits say "this is an int pointer but I
don't know how many ints it points at", that's all.
The OP, OTOH, was looking into hash tables. For hash tables, in most
cases, the bit-by-bit make-up of the object hashed _is_ important. So in
his case, the loss of extra information probably would make the void *
converted pointer incompatible with the original - not as a pointer, but
as a hashed object.

Richard
 
T

Thad Smith

Richard said:
Willem said:


Not without facing up to the possibility that information will be lost
in one direction or the other - this *will* happen if the two types are
not identical in size. If that doesn't matter to him, fine, but I
suspect that it does. (Naturally, my suspicion could be wrong.)

My understanding is that the OP wanted space to store one or the other,
and would not be type punning, so it would be safe.
 
C

Charlie Gordon

Willem said:
Rob wrote:
) I'm working on a hashtable-based dictionary implementation in C, and it
) uses void pointers for data storage, naturally. However, since one of
) the data types I will be using it for is unsigned long -> unsigned
) long, I figure it'd be a better idea to just cast the unsigned longs
) I'm inserted into the void pointer slots to avoid mallocs, frees, and
) unnecessary deferencing. On my machine, this is fine; void * are 32
) bits. Is this necessarily the case on all machines as per the C
) standard? I poured over the C89 specs and couldn't find anything on
) pointer size; I assume that it's always native word size, which would
) require me to think up a different solution.

Can't you use a union of long and void * ?

There is no guarantee that sizeof(void*) <= sizeof(long)
Indeed win64 is a counter example, with sizeof(long)==sizeof(int) ==4 and
sizeof(size_t)== sizeof(void*)==sizeof(long long) == 8.

You could use a union of void* and uintptr_t
 

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,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top