SDCC trunk r16960 fails while building the pic16 (PIC18) device library.
Environment:
Failure:
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:223: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:240: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:257: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:274: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:291: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:316: error 272: invalid width for bit-precise integer type
The failing target is:
device/lib/pic16/libsdcc/_mullonglong.o
_mullonglong.c contains:
#include <stdbit.h>
#include <stdint.h>
#include <sdcc-lib.h>
However, _mullonglong.c does not use any stdbit.h API, stdc_* macro or related bit operation.
Removing only:
#include <stdbit.h>
allows _mullonglong.o to compile successfully and the PIC18 libsdcc.a archive to be created.
Minimal patch:
--- device/lib/_mullonglong.c (revision 16960)
+++ device/lib/_mullonglong.c (working copy)
@@ -26,7 +26,6 @@
-#include <stdbit.h>
#include <stdint.h>
#include <sdcc-lib.h>
After this change the complete Windows/MSYS2 build successfully proceeds through the PIC18 libsdcc build.
Title: PIC16/PIC18 libsdcc build fails because _mullonglong.c unnecessarily includes stdbit.h
Environment:
While building the PIC16/PIC18 device library, the build fails at:
device/lib/pic16/libsdcc/_mullonglong.o
with:
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:223: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:240: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:257: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:274: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:291: error 272: invalid width for bit-precise integer type
R:/sdcc-code_16959/sdcc/device/include/stdbit.h:316: error 272: invalid width for bit-precise integer type
The failing source file contains:
However, mullonglong.c does not use any stdbit.h API, stdc* macro, or related bit operation.
Removing only the unused include:
--- device/lib/_mullonglong.c (revision 16960)
+++ device/lib/_mullonglong.c (working copy)
@@ -26,7 +26,6 @@
allows _mullonglong.o to compile successfully.
After this change:
The include therefore appears to be unnecessary and causes the PIC16/PIC18 build to enter stdbit.h code using unsupported bit-precise integer widths.
Note: the root cause seems to be in stdbit.h itself, not in _mullonglong.c.
A file containing only
#include <stdbit.h>fails the same way with sdcc -mpic16 -p18f452 -c test.c
(error 272 at stdbit.h lines 223, 240, 257, 274, 291, 316).
Removing the include from _mullonglong.c is only a workaround;
stdbit.h probably needs a guard based on __BITINT_MAXWIDTH__
(or the pic16 port reports a too small BITINT maximum width).
Last edit: Maarten Brock 2026-10-05
Diff:
_mullonglong.c uses __STDC_ENDIAN_* macros which come from stdbit.h so its include cannot be removed.
I investigated this further and found two separate issues.
First, the original
_mullonglong.cfailure is caused by the six unconditionalunsigned _BitInt(8)helper declarations instdbit.h:__stdc_leading_zeros
__stdc_trailing_ones
__stdc_first_leading_one
__stdc_first_trailing_one
__stdc_count_ones
__stdc_bit_width
The corresponding six definitions in
device/libalso useunsigned _BitInt(8).I changed only those return types, in both declarations and definitions, to
uint8_t. After that, all sixdiagnostics disappeared.
The implementations only return bit counts or positions in the range 0..ULLONG_WIDTH, and they already contain assertions such as:
static_assert(INT_FAST8_MAX >= ULLONG_WIDTH, "Unsuitable return type");
so
uint8_tseems sufficient while preserving the intended 8-bit return type without requiring_BitInt(8)support.After that change I found a second, independent PIC16 issue.
A minimal C11 test:
inline unsigned char bar(unsigned char x) { return x; }
void foo(void) {}
compiled with:
produces:
global _bar
global _foo
but no
_bar:definition is emitted.A used version:
inline unsigned char bar(unsigned char x) { return x; }
unsigned char foo(unsigned char x) { return bar(x); }
also emits
global _bar, while the call is inlined and no_bar:definition is present.This causes gpasm to reject the generated assembly when gpasm sees the undefined global symbol.
For comparison:
static inline unsigned char bar(unsigned char x) { return x; }
does not emit
global _bar; SDCC emits a local_bar:body instead.So I think the
globalemission for a C11 inline definition without an external definition is a separate PIC16 backend issue.stdbit.hexposes it because it contains many plaininlinedefinitions.I would therefore treat these independently:
_BitInt(8)helper return types withuint8_t.global.Regarding 1.: AFAIR, the
_BitInt(8)was used since it resulted in more efficient code due to not promoting to int. So I would recommend against unconditionally replacing it. Maybe replace it for pic only? Or only ifBITINT_MAXWIDTHis less than 8?P.S.: The value of
BITINT_MAXWIDTHcan be accessed as__SDCC_BITINT_MAXWIDTHif there is a reason to not includelimits.h.Last edit: Philipp Klaus Krause 6 days ago
For PIC16,
__SDCC_BITINT_MAXWIDTHexpands to0.I tried the conditional approach you suggested: keep
unsigned _BitInt(8)when__SDCC_BITINT_MAXWIDTH >= 8, otherwise fall back touint8_t.With that change, all six
invalid width for bit-precise integer typeerrors disappear on PIC16, while targets supporting_BitInt(8)keep the more efficient type.The build then proceeds to the separate PIC16 inline/global issue.
I tested the conditional approach.
For PIC16, __SDCC_BITINT_MAXWIDTH is 0. Using _BitInt(8) when __SDCC_BITINT_MAXWIDTH >= 8 and uint8_t otherwise removes the invalid-width errors while preserving _BitInt(8) on targets that support it.
I also fixed the separate PIC16 issue where non-static inline functions were added to publics even though no external definition was emitted.
With both changes:
the minimal inline test no longer emits global _bar;
_mullonglong.o builds successfully;
the complete device/lib/pic16 build finishes with PIC16_LIB_EXIT=0.
I have attached the two changes as separate patches.
Last edit: zeynelsagcan 6 days ago
Thanks. The stdbit.h patch is in [r16989].
Related
Commit: [r16989]
The inline patch is in [r16990] (without the commented-out line).
Related
Commit: [r16990]