Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C, Creating a 32 bit pointer to a 8 bit array

Tags:

arrays

c

pointers

I have a buffer where each entry in the buffer is 8 bits in size:

uint8_t Buffer[10] = {0x12,0x34,0x56,0x78,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6};

What I need to do is to create pointers to that array, for example 16 bit and 32 bit pointers. For example:

uint32_t *x;
x = Buffer;

uint32_t *y;
y = Buffer+4;

uint16_t *z;
z = Buffer+8;

Where each variable would then read from the array, for example:

x = 0x78563412
y = 0xf4f3f2f1
z = 0xf6f5

This works completely fine, the problem is that I'm getting warnings about incompatible pointer types. So I was wondering if there is an alternative way of doing this or if I'll just have to live with the warnings? Or am I simply doing this completely the wrong way?

Please note that this code will be executed on a single type of platform where the endianness is always the same and the size of data types is always the same.

like image 893
gislibergur Avatar asked Dec 24 '22 05:12

gislibergur


1 Answers

You should heed the warnings; what you're doing is undefined behavior. Type aliasing like that is undefined behavior, particularly since there is no guarantee that Buffer has the correct alignment such that it can be accessed as an int/short. If Buffer has the correct alignment, then you can just explicitly cast and it's okay (and the warning will go away).

You have two options:

One, you align the buffer as the larger of the two types. Be careful that your pointer arithmetic doesn't throw off the alignment:

#include <stdalign.h>

alignas(int) unsigned char Buffer[10] = {0x12,0x34,0x56,0x78,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6};

unsigned int *x;
x = (unsigned int*)(Buffer);

unsigned int *y;
y = (unsigned int*)(Buffer+4);

unsigned short *z;
z = (unsigned short*)(Buffer+8);

Two, you create an unsigned int/unsigned short variable and then memcpy the bytes you're interested in into the variable:

unsigned int x;
memcpy(&x, Buffer, 4);

unsigned int y;
memcpy(&y, Buffer + 4, 4);

unsigned short z;
memcpy(&z, Buffer + 8, 2);
like image 117
Cornstalks Avatar answered Jan 04 '23 20:01

Cornstalks