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.
RCC->CFGR
is alsouint32_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. \$\endgroup\$