cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeIDE: Format specifier concerns

RajeevAroraCrcEvans
Associate III

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
Andrew Neil
Evangelist III

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

 

View solution in original post

7 REPLIES 7
Andrew Neil
Evangelist III

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

 

Thanks! I will test it out.

TDK
Guru

>  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".

@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]

😎

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

 

 

 

Pavel A.
Evangelist III

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 ((

 


@Pavel A. wrote:

these format macros are maddening ((


Aren't they just?! 🙄😳

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

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