views:

77

answers:

3

I'm fairly sure the answer to this is 'no, don't be stupid', but as they say, there are no stupid questions (only stupid people asking them).

I want to calculate the offset of an array. I have a void * handle to it and the sizeof(element). I don't have an x* pointer (where x is the type of the element).

Is there any way I can cast the void * pointer to one of a given size so I can do pointer arithmetic based on that size? At the moment I'm casting to a char * (assuming a char is 1 byte*) and then multiplying the sizeof value by the offset. If I could somehow cast the pointer, then I could just use the array syntax, which would be cleaner.

As I say, I'm 99% sure this isn't possible and I'm basically asking for language-level type representation which C doesn't have. But worth an ask.

*And I'd rather not because it's not always true.

A: 

In C, casting is a compile time-only operation. As such, it isn't possible to determine the actual type of array element at run time.

sizzzzlerz
+3  A: 

As several people have said in comments, sizeof(char) is guaranteed to be 1. The relevant part of the C99 standard is in section 6.5.3.4, describing the sizeof operator:

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result [of the sizeof operator] is 1.

This means that casting the void * to char * and adding N * sizeof(element) is correct and idiomatic.

(C is statically typed, so you can't cast to a type determined at runtime).

caf
+2  A: 

You can't do introspection in C, but that doesn't prevent you from casting anything to anything.

void *v = whatever;
char *c = (char*)v;
c[0] = stuff;
element *e = (element*)v;
e[42].foo = bar;

If you want arbitrary size at runtime, then I don't believe there is a standardized way of doing it. Some compilers support:

char c[x];

where x is a variable, but I wouldn't trust it on all architectures.

You can definitely write a couple simple accessors for your pointers to at least separate out the pointer-math:

void* pointerAtPos( void*p, int offset, int width )
{
  return (void*)&( ((char*)p)[ offset * width ] );
}

Be careful of address alignment.

eruciform
Thanks. That last snippet is what I'm doing currently. Looks like it's the only way.
Joe
+1 That last actually answers his question.
egrunin