recasting a pointer

K

kamran

Hi

I was wondering if it is possible to recast a pointer in C ?
What I mean in detail is that I have compressed data coming from
an instrument. These are mostly sample differences from the
previous sample value. If there has been a small change in the
value of the new sample compared with a previous one, then
only one byte is enough to represent that value. If slightly
greater difference between the two sample value, data is
represented with two bytes and 3 bytes for even larger and
so on.
Now I have a pointer which is declared void :
(void *sample_difference)
and want to recast it to the appropriate type eg. (short *).
But it doesn't work. The compiler complains about a void pointer
can not point to another type. So I use "realloc" to try to
recast the pointer and no change is taking place. The pointer still
remains a void and the resulting value assignment is wrong.

I want to avoid to declare four different variables for
different sample values. Is it possible to only have one
variable and then recast it to the proper type ?


Thanks in advance

Kamran
 
M

Michael B Allen

Hi

I was wondering if it is possible to recast a pointer in C ? What I mean
in detail is that I have compressed data coming from an instrument.
These are mostly sample differences from the previous sample value. If
there has been a small change in the value of the new sample compared
with a previous one, then only one byte is enough to represent that
value. If slightly greater difference between the two sample value,
data is represented with two bytes and 3 bytes for even larger and so
on.
Now I have a pointer which is declared void : (void *sample_difference)
and want to recast it to the appropriate type eg. (short *). But it
doesn't work. The compiler complains about a void pointer can not point
to another type.

Post some code. Are you doing something like:

void
myfn(void *sample_difference)
{
short *s = sample_difference;

/* use s; this should work */
}

Mike
 
K

Kevin Goodsell

Hi

I was wondering if it is possible to recast a pointer in C ?
What I mean in detail is that I have compressed data coming from
an instrument. These are mostly sample differences from the
previous sample value. If there has been a small change in the
value of the new sample compared with a previous one, then
only one byte is enough to represent that value. If slightly
greater difference between the two sample value, data is
represented with two bytes and 3 bytes for even larger and
so on.
Now I have a pointer which is declared void :
(void *sample_difference)
and want to recast it to the appropriate type eg. (short *).
But it doesn't work. The compiler complains about a void pointer
can not point to another type.

There's no obvious reason why the compiler would complain about this.
Conversion from void * to any other object pointer type is allowed.
However, it could fail at runtime if the alignment is incorrect. You
cannot, in general, take any random memory location and interpret it as
an arbitrary type. Some types may need to be aligned on particular
addresses - for example, a two-byte short might need to appear at an
even address.
So I use "realloc" to try to
recast the pointer and no change is taking place. The pointer still
remains a void and the resulting value assignment is wrong.

I don't understand this at all.
I want to avoid to declare four different variables for
different sample values. Is it possible to only have one
variable and then recast it to the proper type ?

A variable never changes its type. That's simply not possible in C. A
cast expression only translates a value to a different type - the source
object is unaffected.

Your description leaves out many details, but my guess is that you need
something like this:

#include <limits.h> /* for CHAR_BIT */

unsigned long value;
int i;

/* Read n bytes: */
value = 0;
for (i=0; i<n; ++i)
{
value = (value << CHAR_BIT) | GetNextByte();
}

/* Now use value somehow. */

-Kevin
 
K

Keith Thompson

Kevin Goodsell said:
There's no obvious reason why the compiler would complain about
this. Conversion from void * to any other object pointer type is
allowed. However, it could fail at runtime if the alignment is
incorrect. You cannot, in general, take any random memory location and
interpret it as an arbitrary type. Some types may need to be aligned
on particular addresses - for example, a two-byte short might need to
appear at an even address.

One obvious workaround for this is to use memcpy().

For example:

void *ptr = some_value;
short s;

/* s = *((short*)ptr); */
memcpy(&s, ptr, sizeof(short));

In the assignment statement that I commented out, ptr is converted
from void* to short*, and the result is dereferenced, yielding a short
value which is assigned to s. However, this will invoke undefined
behavior if ptr isn't properly aligned. (For example, if ptr points
to an odd address, you're likely to get a bus error, but this is
implementation-specific; all you really need to know is Don't Do That.)

The memcpy() call does essentially the same thing, but it operates
byte-by-byte, so it won't have problems with misaligned pointers.
(The implementation of memcpy() might be optimized to copy data a word
at a time if it's safe to do so.)

This assumes that the data ptr points to has the correct byte
ordering. If a short is 2 bytes long, the high-order and low-order
bytes can appear in either order. This can be an issue if you're
copying data from one platform to another. If you read and write the
data on a single system, you probably don't have to worry about this.

A digression: When I wrote "all you really need to know is Don't Do
That", I meant that that's all you need to know to write correct code.
If programming were just about writing correct code, though, we'd all
have a lot more free time. C's "undefined behavior" covers any
possible or impossible behavior, but knowing something about the
implementation-specific details can be extremely useful in tracking
down bugs. (For the most part, those details are best discussed in
implementation-specific newsgroups, though.)
 

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
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top