C Programming - What is 2U or 8U in struct

133 Views Asked by At

Code from this link: https://github.com/openwch/arduino_core_ch32/blob/main/libraries/USBPD_SINK/src/usbpd_def.h

I am looking at the previous file. I did some search and found something about unsign int literal. However, I am not sure how it would make sense in this case and hope someone can explain it to me.

typedef struct 
{
    uint32_t MaxOperatingCurrent10mAunits : 10u;
    uint32_t OperatingCurrentIn10mAunits  : 10u;
    uint32_t Reserved20_21                : 2u; // 00b
    uint32_t EPRModeCapable               : 1u; 
    uint32_t UnchunkedExtendedMessage     : 1u;
    uint32_t NoUSBSuspend                 : 1u;
    uint32_t USBCommunicationsCapable     : 1u;
    uint32_t CapabilityMismatch           : 1u;
    uint32_t GiveBackFlag                 : 1u;
    uint32_t ObjectPosition               : 4u;
}USBPD_SinkFixedVariableRDO_t;

Is this struct has the total size of 44 bytes assume 32bits padding? And what is the 10u, 2u at at the end of each struct member?

2

There are 2 best solutions below

0
Lundin On

This is a non-portable type of struct known as bit-field, where some members have a size in bits as specified by the : n after each member. So MaxOperatingCurrent10mAunits is 10 bits large and so on. The bit order is not specified by the C language so it could be anything.

The general recommendation is to always avoid bit-fields and use bit masks and bit shifts with the bitwise operators instead, since they are portable and deterministic. Unlike bit-fields which are severely under-specified by the C standard.

That the bit sizes in this case is specified as unsigned integer constants ending with u/U have no significance. It is general good practice to always use unsigned ones instead of signed, but it doesn't matter in this specific case. Some coding standards like MISRA C enforce unsigned constants wherever an unsigned type is intended, so the bit sizes could be written with u just to silence a MISRA checker.

0
Andpuv On

I personally don't use bit-fields often so I'm not sure of my answer.

As far as I remember, they can be used to optimize the memory footprint of the program by using the same 32-bit integer (in this case) to store more information. So, unless there are particular compiler speed optimizations that can make it faster to access a 32-bit integer for each field instead of doing bit-mask and shift, the structure should have the size of 4 bytes because by adding all the field-sizes (those numbers after the colon) we reach 32 bits.

As said by others, it is not advisable to use them especially when it is necessary to know the position of the bit to be masked (for example the status flags in some kind of hardware emulator). I think the only pro of bit-fields are that the compiler can generate warnings if you try to assign to the field a value that is out of field range.