Mismatching integer type definitions, stdint.h

Hi all,

I am having difficulties figuring out standard integer types. I am on a Raspberry Pi using arduino-cli and I am trying to use sprintf on an int32_t, with the "%d" format specifier.

sprintf(repr_sizes[i], "%-5s %4d bytes (%3d%%)", NAMES[i], sizes[i], percentage);

When I try to compile my code, the compiler warns me about:
"format '%d' expects argument of type 'int', but argument 4 has type 'int32_t {aka long int}'"

However, when I change it to use "%ld" instead, for long int, my linter clangd says this:
"Format specifies type 'long' but the argument has type 'int32_t' (aka 'int')"

I seem to be getting mismatching info here. Looking closer at the only AVR stdint.h on my system, I find the following code (line 129):

typedef signed int int32_t __attribute__ ((__mode__ (__SI__)));

Which seems to agree with clangd. But lines 125-134 of stdint.h seem to define all integer types as signed or unsigned int, which is strange. But then on line 98 of the same stdint.h, I find this code:

typedef signed long int int32_t;

This code is under an #if defined(__DOXYGEN__) block from lines 66-121. Which begs the question, why does the Doxygen version have different definitions if the only difference is documentation? Is this a bug in the implementation, a copy-paste error perhaps, or am I getting something wrong here?

Can anyone clarify this? Thanks in advance!

stdint.h (16.3 KB)

Update: adding -D__DOXYGEN__ to my linter config caused other problems due to other library code being removed if __DOXYGEN__ is present.

For now I am fixing it by replacing this code (lines 125-134):

typedef signed int int8_t __attribute__((__mode__(__QI__)));
typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
typedef signed int int16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));
typedef signed int int32_t __attribute__ ((__mode__ (__SI__)));
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__)));
#if !__USING_MINT8
typedef signed int int64_t __attribute__((__mode__(__DI__)));
typedef unsigned int uint64_t __attribute__((__mode__(__DI__)));
#endif

With this:

typedef signed char int8_t; // __attribute__((__mode__(__QI__)));
typedef unsigned char uint8_t; // __attribute__((__mode__(__QI__)));
typedef signed int int16_t; // __attribute__ ((__mode__ (__HI__)));
typedef unsigned int uint16_t; // __attribute__ ((__mode__ (__HI__)));
typedef signed long int int32_t; // __attribute__ ((__mode__ (__SI__)));
typedef unsigned long int uint32_t; // __attribute__ ((__mode__ (__SI__)));
#if !__USING_MINT8
typedef signed long long int int64_t; // __attribute__((__mode__(__DI__)));
typedef unsigned long long int uint64_t; // __attribute__((__mode__(__DI__)));
#endif

I fixed the definitions of the int types, and removed the __attribute__s because those confused clangd.

Not sure if patching the library header like this is a good idea or if it's even correct but it works for me for now.

You should NEVER edit the header files that come with your compiler/toolchain.

Different systems and implementations have different integer sizes, you cannot simply edit the system header defining them, you'll end up with fixed-size integer types with the wrong sizes ...

The warnings are valid: %d is not the correct format specifier for int32_t. The correct one is PRId32 from inttypes.h.

#include <inttypes.h>

sprintf(repr_sizes[i], "%-5s %4d bytes (%3" PRId32 "%%)", NAMES[i], sizes[i], percentage);

https://en.cppreference.com/w/cpp/header/cinttypes

Hi, thanks for the fast reply!

According to my inttypes.h, PRId32 is simply defined as "ld" which still doesn't fix my issue that clangd still gives this warning:
Format specifies type 'long' but the argument has type 'int32_t' (aka 'int')

Hence why I edited my stdint.h: to make clangd understand the int32_t is actually long int.

That doesn't matter. All that matters is that it matches the definition of the corresponding integer type. If your installation is consistent, you should not get any warnings.

Did you undo all your changes to the system headers? How did you set up clangd?

Hi, yes I don't have any warnings, it's just clangd that has the issue.

This is my clangd configuration file:
compile_flags.txt (1.1 KB)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.