I face the following. I have a struct like this:
typedef struct
{
uint8 nibble_1 : 4;
uint8 nibble_2 : 4;
uint8 data_1;
uint8 data_2;
uint8 data_3;
} NibbleStruct;
Background information: It is a 32 bit message for CAN communication.
In the code I have the following:
...
NibbleStruct nibble_struct;
uint8 nibble_to_assign = 0U;
nibble_struct.nibble_1 = nibble_to_assign;
...
I need to retain the GCC (gnu99) flag -Werror=conversion
but that gives the error message:
file_name.c error: conversion to 'unsigned char:4' from 'uint8' may alter its value [-Werror=conversion]|
I tried to cast with something like
...
nibble_struct.nibble_1 = (uint8:4) nibble_to_assign; // invalid code
...
and
...
nibble_struct.nibble_1 = (uint8) nibble_to_assign : 4; // invalid code
...
but was not surprised that this does not compile.
Is there any way to cast my variable nibble_to_assign
to the nibble nibble_1
of the struct? Or to declare a nibble in the code outside a struct.
It is recommended to drop "garage standard" uint8
for ISO C standard uint8_t
.
There's various things to keep in mind here:
uint8_t
is not supported by the C standard - this is a non-portable compiler extension.-Wconversion
is a shaky compiler option which is prone to false positives and misleading diagnostics. It is good to use for stress testing/code review but not something you should include in your normal build.The issue that -Wconversion
whines about in this case is that can apparently not predict if the uint8_t
value will fit inside a 4 bit bit-field.
I was able to silence it by forcing an unsigned promotion to unsigned int
:
nibble_struct.nibble_1 = nibble_to_assign & 0xFu;
But please note that neither structs nor bit-fields are particularly suitable or recommended for modelling hardware or data protocols. There may be padding bytes or padding bits inside the struct. If you insist on using the struct, you may have to write serialization/deserialization routines to avoid issues with padding. You may have to do this anyway to handle endianess, since CAN is most often (but not always) using big endian.