I have a simple function in C which provides a void* pointer to a data array. I know the size (in bytes) of each individual data-point within this memory block, and need to guarantee that I can modify each data-point in this block without accidentally altering neighboring data-points. In this example, I want to decrement each value by 1.
All data points are either 8-bit, 16-bit, or 32-bit.
eg:
void myFunction(void* data, size_t arraySize, size_t widthPerDataPoint)
{
if(!data)
return -1;
size_t w = widthPerDataPoint;
int numPoints = arraySize / widthPerDataPoint;
int i;
for(i=0; i<numPoints; i++)
{
if(w==1) // 8 bit
(*((int8_t*)data + i))--;
else if(w==2) // 16 bit
(*((int16_t*)data + i))--;
else if(w==4) // 32 bit
(*((int32_t*)data + i))--;
}
}
Unfortunately, the int8_t, etc, datatypes only guarantee their minimum size, according to C99 specifications, and not an exact size. Is there any way to re-cast and modify the data in-place and guarantee I won’t smash my array or touch neighboring data points? Also, is there an equivalent technique that would somehow work for other data widths (ie: 24-bit, 60-bit, etc)?
int8_tis guaranteed to be exactly 8 bits, and ifCHAR_BIT==1, exactly 1 byte.Quoting the N1570 draft of the latest C standard, section 7.20.1.1:
Though for your purposes it might make more sense to use
uint8_t,uint16_t, et al.If the implementation doesn’t support types with the required characteristics, it won’t define them; you can detect this by checking, for example:
(If
CHAR_BIT != 8, then neitherint8_tnoruint8_twill be defined.)It’s the
[u]intleast_N_tand[u]intfast_ttypes for which the standard only guarantees minimum sizes.You’ll have to guarantee that both the array and the offsets within it are properly aligned for the types you’re using to access it. I presume you’re already taking care of that.