Adding the suffix U to all hexadecimal constants makes them unsigned, as you already mentioned. This can have undesirable side effects when these constants are used in operations along with signs, especially comparisons.
Here is a pathological example:
#define MY_INT_MAX 0x7FFFFFFFU // blindly applying the rule if (-1 < MY_INT_MAX) { printf("OK\n"); } else { printf("OOPS!\n"); }
The C rules for signed / unsigned conversions are well defined, but somewhat counterintuitive, so the code above will actually print OOPS .
The MISRA-C rule is accurate because it indicates that the suffix "U" applies to all constants of an unsigned type. The word unsigned has far-reaching consequences, and most constants should not be considered unsigned.
In addition, the C-standard makes the difference in summation between decimal and hexadecimal constants:
- A hexadecimal constant is considered unsigned if its value can be represented by an unsigned integer, rather than an integer type with a sign of the same size for
int types and larger.
This means that in 32-bit systems the additions 2147483648 have long or long long , while 0x80000000 is unsigned int . Adding the U suffix may make this more explicit in this case, but the real precaution to avoid potential problems is to mandate the compiler to refuse signature / unsigned gcc -Wall -Wextra -Werror : gcc -Wall -Wextra -Werror or clang -Weverything -Werror are life savers.
Here's how it goes wrong:
if (-1 < 0x8000) { printf("OK\n"); } else { printf("OOPS!\n"); }
The above code should print OK on 32-bit systems and OOPS on 16-bit systems. To further aggravate the situation, it is still widely believed that embedded projects use outdated compilers that do not even use standard semantics for this problem.
For your specific question, certain values ββfor microprocessor registers used specifically for their installation through assignment (provided that these registers are mapped to memory), it is not necessary to have the suffix U The value l of the register must be of an unsigned type, and the hexadecimal value will be signed or unsigned, depending on its value, but the operation will continue. The operation code to set the number with or without a sign is the same for your target architecture and any architectures I have even seen.