Skip to main content
Associate III
February 23, 2024
Solved

STM32CubeIDE: Format specifier concerns

  • February 23, 2024
  • 3 replies
  • 7029 views

Hi,

I am using STM32CubeIDE to build project fro STM32H753 microcontroller.

I am unaware why the STM32CubeIDE is updating the type of uint32_t to unsigned long.

I assume for a 32 bit processor uint32_t should be typed to unsigned int.

Where do I find declaration of __UINT32_TYPE__ ?

/* Sample code to report issue */

uint32_t my_id = "1234";

sprintf( tmpstr, "Ser# %08X\r\n", my_id );

 

On compiling code I observe:

../User_Code/File_Xxx.c:205:36: warning: format '%X' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]

205 | sprintf( tmpstr, "Ser# %08X\r\n", my_id );

| ~~~^ ~~~~~~~~~~~~

| | |

| | uint32_t {aka long unsigned int}

| unsigned int

| %08lX


Is there a way I can instruct STM32CubeIDE to type case uint32_t to unsigned int.

I also want to ensure that my change is not overwritten when I regenerate the code with help of IOC file.

 

Regards,

Rajeev

 

Best answer by Andrew Neil

The correct way to do this is to use the format specifiers from inttypes.h; eg, PRIx32 for uint32_t

eg,

uint32_t my_id = "1234";

sprintf( tmpstr, "Ser# %08" PRIx32 "\r\n", my_id );

 

https://en.wikibooks.org/wiki/C_Programming/inttypes.h

 

BTW: Use this button to get the code formatting:

AndrewNeil_1-1708689288544.png

 

3 replies

Andrew Neil
Andrew NeilBest answer
Super User
February 23, 2024

The correct way to do this is to use the format specifiers from inttypes.h; eg, PRIx32 for uint32_t

eg,

uint32_t my_id = "1234";

sprintf( tmpstr, "Ser# %08" PRIx32 "\r\n", my_id );

 

https://en.wikibooks.org/wiki/C_Programming/inttypes.h

 

BTW: Use this button to get the code formatting:

AndrewNeil_1-1708689288544.png

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate III
February 23, 2024

Thanks! I will test it out.

TDK
February 23, 2024

>  uint32_t my_id = "1234";

This won't even compile.

Unable to reproduce the issue even if I take out the quotes.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Andrew Neil
Super User
February 23, 2024

@TDK wrote:

This won't even compile.


It will compile, but with a warning about that initialiser:

warning: initialization of 'uint32_t' {aka 'long unsigned int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]

8)

EDIT

In addition to the OP's warning:

 

 warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t' {aka 'long unsigned int'} [-Wformat=]
 65 | sprintf( tmpstr, "Ser# %08x\r\n", my_id );
 | ~~~^ ~~~~~
 | | |
 | | uint32_t {aka long unsigned int}
 | unsigned int
 | %08lx

 

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Pavel A.
February 23, 2024

Unfortunately even for 32-bit platform, GCC and the newlib library define int32_t as long. Even though int and long  are same physical types, the compiler distinguishes them and requires printf format %ld or %lu. Or %lX.

Agree with Andrew about inttypes.h, but these format macros are maddening ((

 

Andrew Neil
Super User
February 23, 2024

@Pavel A. wrote:

these format macros are maddening ((


Aren't they just?! :face_with_rolling_eyes::flushed_face:

Could they have made it more klunky if they'd tried?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Pavel A.
February 23, 2024

Well, the C++ way (ostream and operator << ) handles it automatically, but it takes conversion to C++. Variadic C functions are a headache.