Hi Thorsten, On Wed, Mar 19, 2025 at 04:56:32PM +0100, Thorsten Glaser wrote: > On Tue, 18 Mar 2025, Alejandro Colomar wrote: > > >> To address this adoption problem, how about changing these function to > >> generic functions (in the sense of <tgmath.h>)? In such a way that > >> strtoi (n, &end, base, LONG_MIN, LONG_MAX, &status) > >> is known to return a 'long' rather than 'intmax_t', and > >> strtoi (n, &end, base, INT_MIN, INT_MAX, &status) > > That, and especially… Please propose an implementation of the overload-selectinging macro, and clarify how this should work: n = strto*(s, NULL, 0, SHRT_MIN, UINT_MAX, &status); Do we use typeof(min + max)? Which is the type to use? Also, aren't you worried about going inventive in the standard? I feel safer with this old API than one invented now. > >I have designed a better API, through a type-generic macro: > > > > int > > a2i(typename T, T *restrict n, QChar *s, > > QChar *_Optional *restrict endp, int base, > > T min, T max); > […] > > … this is a nightmare. This effectively will prevent people from > adding that to systems that do not use C2y as primary/only target > yet, and mixing code. That macro can be implemented with C11. Here's the implementation I wrote for shadow-utils, which we've been using and distributing for a year already: #define a2i(TYPE, n, s, ...) \ ( \ _Generic((void (*)(TYPE, typeof(s))) 0, \ void (*)(short, const char *): a2sh_c, \ void (*)(short, const void *): a2sh_c, \ void (*)(short, char *): a2sh_nc, \ void (*)(short, void *): a2sh_nc, \ void (*)(int, const char *): a2si_c, \ void (*)(int, const void *): a2si_c, \ void (*)(int, char *): a2si_nc, \ void (*)(int, void *): a2si_nc, \ void (*)(long, const char *): a2sl_c, \ void (*)(long, const void *): a2sl_c, \ void (*)(long, char *): a2sl_nc, \ void (*)(long, void *): a2sl_nc, \ void (*)(long long, const char *): a2sll_c, \ void (*)(long long, const void *): a2sll_c, \ void (*)(long long, char *): a2sll_nc, \ void (*)(long long, void *): a2sll_nc, \ void (*)(unsigned short, const char *): a2uh_c, \ void (*)(unsigned short, const void *): a2uh_c, \ void (*)(unsigned short, char *): a2uh_nc, \ void (*)(unsigned short, void *): a2uh_nc, \ void (*)(unsigned int, const char *): a2ui_c, \ void (*)(unsigned int, const void *): a2ui_c, \ void (*)(unsigned int, char *): a2ui_nc, \ void (*)(unsigned int, void *): a2ui_nc, \ void (*)(unsigned long, const char *): a2ul_c, \ void (*)(unsigned long, const void *): a2ul_c, \ void (*)(unsigned long, char *): a2ul_nc, \ void (*)(unsigned long, void *): a2ul_nc, \ void (*)(unsigned long long, const char *): a2ull_c, \ void (*)(unsigned long long, const void *): a2ull_c, \ void (*)(unsigned long long, char *): a2ull_nc, \ void (*)(unsigned long long, void *): a2ull_nc \ )(n, s, __VA_ARGS__) \ ) And here's the definition of one of the overloads: int a2sl_nc(long *restrict n, char *s, char **restrict endp, int base, long min, long max) { int status; *n = strtoi(s, endp, base, min, max, &status); if (status != 0) { errno = status; return -1; } return 0; } > (Besides, a2i is a too generic name.) I named it like atoi(3), just replacing s/to/2/. It is just as generic as the name of the APIs it intends to supersede. > bye, > //mirabilos > PS: Please don’t Cc me explicitly on this thread. Ok. Have a lovely day! Alex -- <https://www.alejandro-colomar.es/>
Attachment:
signature.asc
Description: PGP signature