https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114731

--- Comment #20 from Alejandro Colomar <alx at kernel dot org> ---
Hmmmm, I like the _Generic() to assert the type.  Thanks!

With that, I find it more acceptable.  At least I don't need to use GNU
extensions, and the cast is coupled with the verification of the type.  It's a
bit repetitive, but acceptable.

I agree that using heuristics to fix this would be bad.

Feel free to close as WONTFIX.

Have a lovely day!
Alex


Below is the program using _Generic() to assert the type.


alx@debian:~/tmp/c$ cat g.c
#include <assert.h>
#include <bsd/inttypes.h>
#include <errno.h>
#include <time.h>


#define a2i(TYPE, n, s, endp, base, min, max)                                 \
({                                                                            \
        _Generic((TYPE) 0,                                                    \
                long:               a2sl(_Generic(n, TYPE *: (long *) n), s,
endp, base, min, max), \
                int:                a2si(_Generic(n, TYPE *:  (int *) n), s,
endp, base, min, max)  \
        );                                                                    \
})


#define a2sl(n, s, endp, base, min, max)                                      \
(                                                                             \
        _Generic(endp,                                                        \
                const char **:  a2sl_c,                                       \
                char **:        a2sl_nc,                                      \
                void *:         a2sl_nc                                       \
        )(n, s, endp, base, min, max)                                         \
)

#define a2si(n, s, endp, base, min, max)                                      \
(                                                                             \
        _Generic(endp,                                                        \
                const char **:  a2si_c,                                       \
                char **:        a2si_nc,                                      \
                void *:         a2si_nc                                       \
        )(n, s, endp, base, min, max)                                         \
)


static inline int a2sl_c(long *restrict n, const char *s,
    const char **restrict endp, int base, long min, long max);
static inline int a2si_c(int *restrict n, const char *s,
    const char **restrict endp, int base, int min, int max);

static inline int a2sl_nc(long *restrict n, const char *s,
    char **restrict endp, int base, long min, long max);
static inline int a2si_nc(int *restrict n, const char *s,
    char **restrict endp, int base, int min, int max);


static inline int
a2sl_c(long *restrict n, const char *s,
    const char **restrict endp, int base, long min, long max)
{
        return a2sl_nc(n, s, (char **) endp, base, min, max);
}


static inline int
a2si_c(int *restrict n, const char *s,
    const char **restrict endp, int base, int min, int max)
{
        return a2si_nc(n, s, (char **) endp, base, min, max);
}


static inline int
a2sl_nc(long *restrict n, const 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;
}


static inline int
a2si_nc(int *restrict n, const char *s,
    char **restrict endp, int base, int min, int max)
{
        int  status;

        *n = strtoi(s, endp, base, min, max, &status);
        if (status != 0) {
                errno = status;
                return -1;
        }
        return 0;
}


int
main(void)
{
        time_t  t;

        a2i(time_t, &t, "42", NULL, 0, 0, 10);
}
alx@debian:~/tmp/c$ cc -Wall -Wextra g.c -S
alx@debian:~/tmp/c$

Reply via email to