Menu

#3798 long long library function build issues (__SDCC_LONGLONG)

closed-fixed
None
other
5
2026-03-20
2024-11-10
No

__SDCC_LONGLONG is defined in stdint.h for all ports except pic14. And long long library functions are built and regression tested when it is defined. But some such functions only include stdlib.h, so they never get built and tested.
stdlib.h should define __SDCC_LONGLONG for non-pic14. But doing so currently makes thelibrary build run into further issues.

Related

Bugs: #3746

Discussion

  • Philipp Klaus Krause

    In [r15097], I put the #define in stdlib.h, and disabled the build of strtoull and wcstoull. That way we get at least atoll for now.

     

    Related

    Commit: [r15097]

  • Benedikt Freisen

    I reckon that the remaining issues (in strtoull and wcstoull) are linked to missing checked integer arithmetic for 64 bit types. See [feature-requests:#749].

     

    Related

    Feature Requests: #749

  • Benedikt Freisen

    [r15190] adds the same hack to strtoull and wcstoull that is used in strtoul and wcstoul for ports that do not support (unsigned) long long, and re-enables both functions.
    Checked integer arithmetic for 64 bit types is still missing.

     

    Related

    Commit: [r15190]

    • Janko Stamenović

      It seems this "hack" is implemented in strtoull very differently from strtoul? I see this in my compilation for z80n which uses -Werror and strtoul never caused warning/error, but with this change compiling strtoull.cgives:

      strtoull.c:134:2: error: #warning INEXACT RANGE ERROR CHECK WILL NOT REPORT ALL OVERFLOWS (fix by implementing ckd_mul and ckd_add for unsigned long long) [-Werror]
        134 | #warning INEXACT RANGE ERROR CHECK WILL NOT REPORT ALL OVERFLOWS (fix by implementing ckd_mul and ckd_add for unsigned long long)
            |  ^~~~~~~
      cc1: all warnings being treated as errors
      

      Looking at the sources of strtoul I see:

      #if !defined(__SDCC_pic14) && !defined(__SDCC_pic16)
            range_error |= ckd_mul (&ret, ret, b);
            range_error |= ckd_add (&ret, ret, digit);
      #else
            unsigned long int oldret = ret;
            ret *= b;
            if (ret < oldret)
              range_error = true;
            ret += (unsigned char)digit;
      #warning INEXACT RANGE ERROR CHECK WILL NOT REPORT ALL OVERFLOWS (fix by implementing ckd_mul and ckd_add)
      #endif
      

      (so it seems warning is never reached) but in strtoull.c the equivalent lines are with if 0:

      #if 0
            range_error |= ckd_mul (&ret, ret, b);
            range_error |= ckd_add (&ret, ret, digit);
      #else
            unsigned long long int oldret = ret;
            ret *= b;
            if (ret < oldret)
              range_error = true;
            ret += (unsigned char)digit;
      #warning INEXACT RANGE ERROR CHECK WILL NOT REPORT ALL OVERFLOWS (fix by implementing ckd_mul and ckd_add for unsigned long long)
      #endif
      

      That #if 0 for z80n causes that warning in strtoull.c.

      I still haven't investigated why it's: #if !defined(__SDCC_pic14) && !defined(__SDCC_pic16) in strtoul but only #if 0 in strtoull.c and which of the two is the correct way in the whole context, at this moment I'm just reporting that I see something I haven't seen before.

      Edit: If I understand correctly: it's different sizes of the variables (and then probably different function names should be there?) and #if 0has to be there as that code represents a (not fully implemented?) call to functions which don't exist?

      Edit2: I see now: it's stdckdint.h where other sizes for these functions are, but that ull isn't.

       

      Last edit: Janko Stamenović 2025-01-20
  • Benedikt Freisen

    • status: open --> closed-fixed
     
  • Maarten Brock

    Maarten Brock - 2026-03-20
    • assigned_to: Benedikt Freisen
     

Log in to post a comment.

MongoDB Logo MongoDB