Is it always guaranteed to get a width value where all the bits are zero, except for the bottom 8 of b?
Yes.
The resulting macro type may be different, depending on type b . This can cause portability problems. Therefore, it would be better to make the result a target type, for example uint32_t .
Is there a difference between the two versions
No, they are equivalent.
they must be signed, if necessary,
As a rule, it makes no sense to use bitwise operators for signed types.
If I need a common macro to generate flag constants, will this always result in a flag constant for the specified width?
Yes, but the result will have a different type depending on the size of int or long.
Recently, I ran into a problem when we needed to transfer the serial protocol handler that I wrote to another family of microcontrollers, only to find that the RAM was not addressable for the byte.
Basically a compiler problem. Also, it is unclear how uint8_t will be a problem for such systems; there is always implicit integer progress. It looks like you had some kind of problem with the algorithm, maybe the code using uint8_t* pointers or something like that.
A pedantically fully portable code would look something like this:
#define MASK8_32(x) ((uint32_t)(x) & 0xFFul) #define GEN_FLAG_16(x) (uint16_t)( 0xFFFFu & (1u << (x)) ) #define GEN_FLAG_32(x) (uint32_t)( 0xFFFFFFFFu & (1ul << (x)) )
Currently, most of the potential size and implicit type restrictions have been removed.
The main portability features are important here:
- Your code depends on the size of
int and long . Such code is not portable, as these types can be of any size. Using fixed-width integer types from stdint.h will solve many of these problems. - Your code is not aware of the standardness of default types and integer literals. In many cases, you use bitwise operators for signed operands, which is always bad.
- You generally donβt know how implicit type promotions work in C.
As it turns out, all of these problems can be solved using MISRA-C . I would recommend buying MISRA-C: 2012 and reading it for educational purposes.
As a side note, a code of type a = OBSUCRE_MACRO(b); much less readable than code like a = b & 0xFF; . Because you can always assume that the reader is a C programmer, and as such knows the C language, but does not know your secret macro language.
Functional macros are also unsafe and should be avoided when possible.
So, I ask the question what these macros do well in the first place.