2025-02-11 02:35 PM
I think const-correctness is an important-enough concept to call this a bug report.
I can't speak for the entirety of STM32's library code, but the HAL and related libraries I've used so far are almost universally not const-correct.
What is const-correctness in C?
If a function that accepts a pointer to some data doesn't change that data, the function can tell the calling context that fact by declaring the buffer pointer to be const, like so:
void i_do_not_change_the_data(const void * data_ptr);
Then the calling context can be sure that the function will not attempt to write to the buffer, and can take advantage of compiler and language optimizations surrounding const arguments. One such (poor) example is a string literal, which can serve as a const char * argument, but not a char * argument.
Most (all?) of the HAL functions that take pointers to buffers take non-const pointers, even if those functions don't write to the buffer. That means that I cannot write my own code to be const-correct without casting away the constness, exposing my code to undefined behaviors.
Unfortunately, this problem runs extremely deeply in the library code, all the way down to HAL struct members. TX buffers in particular should be declared as const *, but they're not, so const pointers can't be assigned to them and the APIs can't be corrected.
This needs an intense application of effort to correct. If ST intends its HAL libraries to be suitable for production code, this really ought to be fixed.
All pointer arguments to functions should be const unless they can't be. Const-ness should be a forethought, not an afterthought.
2025-02-11 03:13 PM
> If ST intends its HAL libraries to be suitable for production code
That's a big if.
2025-02-11 04:32 PM
> TX buffers in particular should be declared as const *, but they're not, so const pointers can't be assigned to them and the APIs can't be corrected.
Most buffers are declared this way. For example (F4 SPI as a randomly chosen example):
const uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */
and the calling function takes a pointer to const:
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
Since most functions are changing the peripheral state in some way, it makes sense for most of them to take non-const handles. Things that are read-only take a const handle. For example:
HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi);
Are there specific other examples where you think this should be looked at? Certainly the intention is already there to make things const-correct.