# Are all these C type casts really necessary for bitwise register operations?

I find the coding style in the STM32F0 (ARM Cortex-M0 microcontroller) SPL (standard peripheral library) unnecessarily verbose. As an example, here is a snippet of code for configuring the phase locked loop for SYSCLK:

/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;


Where RCC_CFGR_SW and RCC_CFGR_SW_PLL are macros for integer literals already cast to uint32_t.

#define RCC_CFGR_SW     ((uint32_t)0x00000003)
#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002)


And RCC->CFGR is a (memory mapped) instance of a struct of the type

typedef struct
{
...
__IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x04 */
...
} RCC_TypeDef;


So the result would be implicitly cast to uint32_t anyway, even giving a warning if something funny happens (unlike what would happen with an explicit cast).

Can these explicit casts be eliminated, especially given that C99 guarantees (6.3.1.3) that

• When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

Allowing the simplification of the code to the significantly clearer

//Select the PLL as system clock source
RCC->CFGR &= ~(RCC_CFGR_SW);
RCC->CFGR |= RCC_CFGR_SW_PLL;


Or could that cause some unforeseen side effects? I'm not really sure, and I presume that the people who wrote that code are more experienced writing embedded C than I am...

I'm asking this question on electronics.stackexchange instead stackoverflow since it's quite specific to low level embedded programming.

• Can you guarantee that the outcome of all those expressions is a uint32_t? is 0x00000003 also a uint32_t? Do you really want to worry that it is and think about if or if not it is guaranteed, or do you want to make sure the result is, thus simply tell the compiler htat you want it to be? Sep 19 '16 at 19:40
• "I presume that the people who wrote that code are more experienced writing embedded C than I am" Clearly you haven't got much experience with ST SPLs yet :D Sep 19 '16 at 19:41
• I think stackoverflow would be better. This is exactly what the hardcore C language lawyers deal with, and has been dealing with since 1989 when all the weird C preprocessor+runtime "implicit integer conversions" were standardized. I'm sure you'll get good answers here too though.
– pipe
Sep 19 '16 at 19:42
• Have a look at the Misra rules to get a feeling on why all those casts might be necessary. Sep 19 '16 at 19:47
• gotta agree with @Armandas. and i totally disagree with Arsenal. i know straight ANSI C quite well and, assuming that RCC->CFGR is also uint32_t, then the casts in the first two statements are totally redundant. there are a lot of crappy programmers around that do not realize that, besides making code that works, it is also important to make code concise, readable, and easily maintained. Sep 19 '16 at 20:23

When C converts a signed int to an unsigned int, of the same physical size, the standard requires that the C compiler produce an unsigned result which either (1) has the same equivalent value meaning in the unsigned symbol space, or else; (2) is the signed value modulo $2^{bitsize}$. Such conversions are guaranteed a specific mathematical result. One that most people expect, in fact. However, when an unsigned int is converted to a signed int, again of the same physical size, the standard requires that if and only if there exists an equivalent value meaning, then that meaning must be maintained. If, however, the unsigned value exceeds the limit of positive value meaning, then there is no standard result, at all. The C compiler can, I suppose, generate random nonsense if it wants to.