- Package:
- gcc-arm-none-eabi
- Source:
- gcc-arm-none-eabi
- Description:
- GCC cross compiler for ARM Cortex-R/M processors
- Submitter:
- Jonathan Neuschäfer
- Date:
- 2026-08-09 06:09:01 UTC
- Severity:
- normal
After upgrading to Debian trixie (currently "testing") and thus GCC
13.2.1, inttypes.h doesn't define the 64-bit format specifiers such as
PRIi64 anymore, as demonstrated and explained by the following program:
// $ arm-none-eabi-gcc --version
// arm-none-eabi-gcc (15:13.2.rel1-2) 13.2.1 20231009
//
// $ arm-none-eabi-gcc -c test.c
// test.c: In function 'main':
// test.c:21:31: error: expected ')' before 'PRIi64'
// 21 | printf("the answer: %" PRIi64 "\n", i);
// | ~ ^~~~~~~
// | )
// test.c:18:1: note: 'PRIi64' is defined in header '<inttypes.h>'; did you forget to '#include <inttypes.h>'?
// 17 | #include <inttypes.h>
// +++ |+#include <inttypes.h>
// 18 |
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {
int64_t i = 42;
printf("the answer: %" PRIi64 "\n", i);
return 0;
}
//
// /usr/include/newlib/machine/_default_types.h correctly defines ___int64_t_defined,
// (indentation for emphasis mine, in all code excerpts):
//
// #ifdef __INT64_TYPE__
// typedef __INT64_TYPE__ __int64_t;
// #ifdef __UINT64_TYPE__
// typedef __UINT64_TYPE__ __uint64_t;
// #else
// typedef unsigned __INT64_TYPE__ __uint64_t;
// #endif
// #define ___int64_t_defined 1
// #elif __EXP(LONG_MAX) > 0x7fffffff
// typedef signed long __int64_t;
// typedef unsigned long __uint64_t;
// #define ___int64_t_defined 1
// ...
//
//
// Next, __int64_t_defined would be set in /usr/include/newlib/sys/_stdint.h:
//
// #ifdef ___int64_t_defined
// #ifndef _INT64_T_DECLARED
// typedef __int64_t int64_t ;
// #define _INT64_T_DECLARED
// #endif
// #ifndef _UINT64_T_DECLARED
// typedef __uint64_t uint64_t ;
// #define _UINT64_T_DECLARED
// #endif
// #define __int64_t_defined 1
// #endif /* ___int64_t_defined */
//
//
// sys/_stdint.h would be included via <stdint.h>, but that doesn't happen
// because GCC picks the wrong stdint.h, from /usr/lib/gcc/arm-none-eabi/13.2.1/include/stdint.h.
//
// Finally, PRIi64 and similar macros are not defined in
// /usr/include/newlib/inttypes.h, because __int64_t_defined wasn't defined:
//
// #if __int64_t_defined
// #define PRId64 __PRI64(d)
// #define PRIi64 __PRI64(i)
// #define PRIo64 __PRI64(o)
// #define PRIu64 __PRI64(u)
// #define PRIx64 __PRI64(x)
// #define PRIX64 __PRI64(X)
//
// #define SCNd64 __SCN64(d)
// #define SCNi64 __SCN64(i)
// #define SCNo64 __SCN64(o)
// #define SCNu64 __SCN64(u)
// #define SCNx64 __SCN64(x)
// #endif
//
//
// As a workaround, #include <sys/_stdint.h> before #include <inttypes.h> fixes the issue.
Debian team - My team just hit this bug on production code. https://github.com/BerkeleyLab/Marble-MMC Ugly, ugly, ugly. Thanks, Jonathan, for the thorough analysis and usable workaround. I also confirmed that adding the extra #include <sys/_stdint.h> does not break our build on Debian stable (Bookworm). - Larry
We believe that the bug you reported is fixed in the latest version of gcc-arm-none-eabi, which is due to be installed in the Debian FTP archive. A summary of the changes between this version and the previous one is attached. Thank you for reporting the bug, which will now be closed. If you have further comments please address them to 1067692@bugs.debian.org, and the maintainer will reopen the bug report if appropriate. Debian distribution maintenance software pp. Keith Packard <keithp@keithp.com> (supplier of updated gcc-arm-none-eabi package) (This message was generated automatically at their request; if you believe that there is a problem with it please contact the archive administrators by mailing ftpmaster@ftp-master.debian.org) Format: 1.8 Date: Fri, 31 Jul 2026 17:46:41 -0700 Source: gcc-arm-none-eabi Architecture: source Version: 15:15.3.rel1-1 Distribution: unstable Urgency: medium Maintainer: Keith Packard <keithp@keithp.com> Changed-By: Keith Packard <keithp@keithp.com> Closes: 953844 1067692 Changes: gcc-arm-none-eabi (15:15.3.rel1-1) unstable; urgency=medium . * New upstream release. * Switched to picolibc. (Closes: #953844, #1067692) * Remove autogen dependency. (Closes #1076254) Checksums-Sha1: 506e668af3cfd93104684a4034d3c1f2ebba6ee7 2616 gcc-arm-none-eabi_15.3.rel1-1.dsc 9a665e888b18800674de5bd342a6f6560530b09f 104500411 gcc-arm-none-eabi_15.3.rel1.orig.tar.bz2 ddb800e2e0a1382d649508dfe40b42db4e7ffe52 11952 gcc-arm-none-eabi_15.3.rel1-1.debian.tar.xz 7dda71477a3409206c5624a539737a912e62f18a 9283 gcc-arm-none-eabi_15.3.rel1-1_amd64.buildinfo Checksums-Sha256: b7e1be5547239e2a614efb35c5de282dbe34ab1b2503f8d4ec5b4a8c2894961b 2616 gcc-arm-none-eabi_15.3.rel1-1.dsc d087d40f83d2215b0b9b9c1daca916732333369b3f61d592c4d27a527ab757d1 104500411 gcc-arm-none-eabi_15.3.rel1.orig.tar.bz2 ca52a4437af03e3b267f79626e1567d1ab55c3890b0bd9f10d400fcf1248d43f 11952 gcc-arm-none-eabi_15.3.rel1-1.debian.tar.xz a4454277de2ec35edbbfb729617d8cac3143008e5dac3b45c04ff6b731ade88c 9283 gcc-arm-none-eabi_15.3.rel1-1_amd64.buildinfo Files: 4a3dfb23116f87629d0726b50f519784 2616 devel optional gcc-arm-none-eabi_15.3.rel1-1.dsc 9446d826f08c4495f35e6c2244f4a0c0 104500411 devel optional gcc-arm-none-eabi_15.3.rel1.orig.tar.bz2 03448d4f8221344da1023e48e8bdb828 11952 devel optional gcc-arm-none-eabi_15.3.rel1-1.debian.tar.xz cf7281cefa1bc516e0a030a58716c8ef 9283 devel optional gcc-arm-none-eabi_15.3.rel1-1_amd64.buildinfo -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEw4O3eCVWE9/bQJ2R2yIaaQAAABEFAmptSYMACgkQ2yIaaQAA ABHJPw/9EblFpHXNcVtMKGAQBt6PkH/Q+c0wtNl+tmKy3OEyHw1PLZMzGbjlw7xM X81cMK43K6TGiyJHBieVzBBcANKLPM/rgzuUAUxPXckfiIxp/3zL/ObCqyPQm0Le ClrzOGdWylmx0rzN1Yajp5EsPWSTou75j3gEpB/nk8UlPpJQM9y8irHZWnxhWk14 DxUDEu/hHhf4a66kSk99iEi6DiPEagdkqL0HWqr+u+u+RLPQYqrzXKZQ36g0GktV 6dR+e953SF4EvqHm68kgf8i8y0HCoBI+vZEH8HGR7m3u5VKPYMD1TgaerEw18v+U 0uKgJZ0jRO8XNbmOHWHcuV0ALC/IdaIitb9jsdO69d8A88QRkTLOH6haFsl+JWn2 /dRWO6woB36OcmCK/RBhsjjzP3KLVikNZU5rQN+a36H5aqrv3hpS5ngHdoZ12K4G 5YIg/u6mGDVqJmXrX5jfFqcCj0Ds4Gu46izSAcWphe5FPLotktKM8kfF8ZuWsQwi SVabDw2zujmOX3d//7uLM2KfEWXbSieRccFDV2PLjVq2B5ip5zNPH4cOvrkMvunW B+jYRGf85ek3kGJoGHfuXIwNTcw9vhzRoQku24NrSk7oLqUt8Z/9EzQ/ZPJvUs+p CHXv2nsWt1ir1lwaXt8Z1W+XEMVHr4rxQqEl8MCwX19HSSqE5Z8= =yp9w -----END PGP SIGNATURE-----
package: gcc-arm-none-eabi
Hi,
I can confirm this bug is still reproducible on current Ubuntu (26.04) with
a
newer toolchain. The same root cause documented here is hit by our CI build
of
an embedded firmware project (STM32 Cortex-M, libudpard/cyphal based)
whenever
the code uses the base-64-bit format macros from <inttypes.h>.
Environment:
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:14.2.rel1-1) 14.2.1 20241119
$ grep PRETTY /etc/os-release
PRETTY_NAME="Ubuntu 26.04 LTS"
Minimal reproducer (test.c):
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
int main(void){ uint64_t x = 0x0123456789abcdefULL; printf("%016" PRIx64
"\n", x); return 0; }
Compile with the same flags we use for firmware:
$ arm-none-eabi-gcc -std=c2x -Werror -mthumb -mcpu=cortex-m7 -c test.c
test.c: In function 'main':
test.c:4:66: error: expected ')' before 'PRIx64'
4 | ... printf("%016" PRIx64 ...
| ^~~~~~~
test.c:4:1: note: 'PRIx64' is defined in header '<inttypes.h>'; this is
probably fixable by adding '#include <inttypes.h>'
(The compiler suggestion is misleading: PRIx64 IS defined in inttypes.h but
only conditionally.)
Root cause is exactly as described above: the header search picks up GCC's
own self-contained <stdint.h> ahead of the newlib one:
$ arm-none-eabi-gcc -E -v -x c /dev/null 2>&1 | sed -n "/#include <...>
search/,/End of search list/p"
/usr/lib/gcc/arm-none-eabi/14.2.1/include
/usr/lib/gcc/arm-none-eabi/14.2.1/include-fixed
/usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/include
so `#include <stdint.h>` resolves to
/usr/lib/gcc/arm-none-eabi/14.2.1/include/stdint.h (guarded by
`_GCC_STDINT_H`), which does not include_next <stdint.h>. newlib's
`sys/_stdint.h` (which defines `__int64_t_defined` at line 63) is therefore
never reached, and `/usr/include/newlib/inttypes.h` gates all the
PRI64/SCN64
macros behind `#if __int64_t_defined` at line 216, so none of them are
emitted.
Confirming the include resolution:
$ printf "#include <stdint.h>\n" | arm-none-eabi-gcc -MM -H -x c -o
/dev/null -
. /usr/lib/gcc/arm-none-eabi/14.2.1/include/stdint.h
Workaround, for other people hitting the same CI failure: we chain GCC's
stdint.h into newlib's by appending `#include_next <stdint.h>` to
$(arm-none-eabi-gcc -print-file-name=include/stdint.h), which restores the
behavior of the old wrapper and makes PRIx64/PRId64/PRIu64 all compile.
It would be great if the packaging could either restore the `#include_next
<stdint.h>` wrapper that Debian's `provide-stdint-for-embedded` used to
carry,
or coordinate with libnewlib so that `inttypes.h` does not depend on a macro
that only newlib's own <stdint.h> can define.
Thanks for the excellent analysis already in this bug; please let me know if
you need anything else reproduced.
*Erik Rainey*
erik.rainey@gmail.com
The bug is marked as fixed in version 15:15.3.rel1-1, you're still running an older version.