Skip to main content
Associate III
February 23, 2024
Solved

STM32CubeIDE: Format specifier concerns

  • February 23, 2024
  • 3 replies
  • 7125 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

 

This topic has been closed for replies.
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.