Reputation: 2430
Is there a clean way of casting a struct into an uint64_t or any other int, given that struct in <= to the sizeof int? The only thing I can think of is only an 'ok' solution - to use unions. However I have never been fond of them.
Let me add a code snippet to clarify:
typedef struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
}some_struct_t;
some_struct_t some_struct;
//init struct here
uint32_t register;
Now how do i cast some_struct to capture its bits order in uint32_t register.
Hope that makes it a bit clearer.
Upvotes: 16
Views: 34951
Reputation: 37
Using a user-defined static_cast conversion is simpler than both union and reinterpret_cast/pointer casting: https://en.cppreference.com/w/cpp/language/cast_operator
Upvotes: -2
Reputation: 107
Warning: It can invoke undefined behaviour under certain circumstances using certain compilers. See Andrew Henle's comment. If you will use my answer, learn about -fno-strict-aliasing
compiler flag.
You can cast object's pointer to desired type and then dereference it. Also consider your plaftorm's endianness.
Short example using uint16_t
:
*(uint16_t *)&my_struct
Detailed example using uint16_t
:
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint8_t field1;
uint8_t field2;
} MyStruct;
int main() {
MyStruct my_struct = {0xFA, 0x7D};
uint16_t num_my_struct = *(uint16_t *)&my_struct;
printf("%X \n", num_my_struct); // 7DFA (little-endian machine)
return 0;
}
Upvotes: 4
Reputation: 9
you can use pointers and it will be easy for example:
struct s {
int a:8;
int b:4;
int c:4;
int d:8;
int e:8; }* st;
st->b = 0x8;
st->c = 1;
int *struct_as_int = st;
hope it helps
Upvotes: 0
Reputation: 1572
I've just hit the same problem, and I solved it with a union like this:
typedef union {
struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
} fields;
uint32_t bits;
} some_struct_t;
/* cast from uint32_t x */
some_struct_t mystruct = { .bits = x };
/* cast to uint32_t */
uint32_t x = mystruct.bits;
HTH, Alex
Upvotes: 35
Reputation: 97938
A non-portable solution:
struct smallst {
int a;
char b;
};
void make_uint64_t(struct smallst *ps, uint64_t *pi) {
memcpy(pi, ps, sizeof(struct smallst));
}
You may face problems if you, for example, pack the struct on a little-endian machine and unpack it on a big-endian machine.
Upvotes: 4