Menu ▾ ▴

#4110 PIC16/PIC18 libsdcc build fails because _mullonglong.c unnecessarily includes stdbit.h

pending-fixed
None
PIC16
5
4 days ago
2026-10-04
No

SDCC trunk r16960 fails while building the pic16 (PIC18) device library.

Environment:

  • Windows
  • MSYS2 / MinGW-w64 x86_64
  • SDCC trunk r16960
  • pic16 backend (PIC18)

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.

1 Attachments

Related

Bugs: #4122

Discussion

  • zeynelsagcan

    zeynelsagcan - 2026-10-04

    Title: PIC16/PIC18 libsdcc build fails because _mullonglong.c unnecessarily includes stdbit.h

    Environment:

    • SDCC trunk r16960
    • Windows
    • MSYS2 / MinGW-w64 x86_64
    • PIC16 backend (PIC18)

    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:

    #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 the unused include:

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

    allows _mullonglong.o to compile successfully.

    After this change:

    • _mullonglong.o builds successfully
    • libsdcc.a is created successfully
    • the PIC18 device library build proceeds successfully
    • the complete SDCC build subsequently finishes with BUILD_EXIT_CODE=0

    The include therefore appears to be unnecessary and causes the PIC16/PIC18 build to enter stdbit.h code using unsupported bit-precise integer widths.

     
  • zeynelsagcan

    zeynelsagcan - 2026-10-04

    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
  • Maarten Brock

    Maarten Brock - 2026-10-05
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -17,24 +17,24 @@
    
     The failing target is:
    
    -device/lib/pic16/libsdcc/_mullonglong.o
    +device/lib/pic16/libsdcc/\_mullonglong.o
    
    -_mullonglong.c contains:
    -
    +\_mullonglong.c contains:
    +~~~
     #include &lt;stdbit.h&gt;
     #include &lt;stdint.h&gt;
     #include &lt;sdcc-lib.h&gt;
    -
    -However, _mullonglong.c does not use any stdbit.h API, stdc_* macro or related bit operation.
    +~~~
    +However, \_mullonglong.c does not use any stdbit.h API, stdc\_* macro or related bit operation.
    
     Removing only:
    -
    +~~~
     #include &lt;stdbit.h&gt;
    -
    -allows _mullonglong.o to compile successfully and the PIC18 libsdcc.a archive to be created.
    +~~~
    +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 @@
    @@ -42,5 +42,5 @@
      #include &lt;stdint.h&gt;
    
      #include &lt;sdcc-lib.h&gt;
    -
    +~~~
     After this change the complete Windows/MSYS2 build successfully proceeds through the PIC18 libsdcc build.
    
     
  • Maarten Brock

    Maarten Brock - 2026-10-05

    _mullonglong.c uses __STDC_ENDIAN_* macros which come from stdbit.h so its include cannot be removed.

     
  • zeynelsagcan

    zeynelsagcan - 6 days ago

    I investigated this further and found two separate issues.

    First, the original _mullonglong.c failure is caused by the six unconditional unsigned _BitInt(8) helper declarations in stdbit.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/lib also use unsigned _BitInt(8).

    I changed only those return types, in both declarations and definitions, to uint8_t. After that, all six

    error 272: invalid width for bit-precise integer type
    

    diagnostics 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_t seems 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:

    sdcc --std-c11 -mpic16 -p18f452 -S ...
    

    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 global emission for a C11 inline definition without an external definition is a separate PIC16 backend issue. stdbit.h exposes it because it contains many plain inline definitions.

    I would therefore treat these independently:

    1. Replace the six internal _BitInt(8) helper return types with uint8_t.
    2. Fix PIC16 so that an inline definition for which no external definition is emitted is not nevertheless listed as global.
     
    • Philipp Klaus Krause

      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 if BITINT_MAXWIDTH is less than 8?

      P.S.: The value of BITINT_MAXWIDTH can be accessed as __SDCC_BITINT_MAXWIDTH if there is a reason to not include limits.h.

       

      Last edit: Philipp Klaus Krause 6 days ago
  • zeynelsagcan

    zeynelsagcan - 6 days ago

    For PIC16, __SDCC_BITINT_MAXWIDTH expands to 0.

    I tried the conditional approach you suggested: keep unsigned _BitInt(8) when __SDCC_BITINT_MAXWIDTH >= 8, otherwise fall back to uint8_t.

    With that change, all six invalid width for bit-precise integer type errors disappear on PIC16, while targets supporting _BitInt(8) keep the more efficient type.

    The build then proceeds to the separate PIC16 inline/global issue.

     
  • zeynelsagcan

    zeynelsagcan - 6 days ago

    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
    • Philipp Klaus Krause

      Thanks. The stdbit.h patch is in [r16989].

       

      Related

      Commit: [r16989]

    • Philipp Klaus Krause

      The inline patch is in [r16990] (without the commented-out line).

       

      Related

      Commit: [r16990]

  • Philipp Klaus Krause

    • status: open --> pending-fixed
    • assigned_to: Philipp Klaus Krause
     

Log in to post a comment.