Alejandro Colomar wrote:
> I've had the idea today of an implementation that would be even better
> for users, not requiring the cast at all.
> 
>       $ cat execve4.c 
>       #include <stddef.h>
> 
>       #ifdef __cplusplus
>       # define const_cast(T, p)  p
>       #else
>       # define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))
>       #endif
> 
>       #ifdef __cplusplus  // Have n3749
>       int execve(const char *path, const char *const a[], const char *const 
> e[]);
>       #else
>       # define execve(p, a, e)  execve(p, const_cast(char*const*,a), 
> const_cast(char*const*,e))
>       int (execve)(const char *path, char *const a[], char *const e[]);
>       #endif

Very nice! This can even be done in Gnulib, without waiting for libc changes.
And for older compilers (that don't support _Generic), we can use an explicit
cast:

        #ifdef __cplusplus
        # define const_cast(T, p)  p
        #elif (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4) \
              || (defined __clang__ && __clang_major__ >= 3) \
              || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) \
              || (__STDC_VERSION__ >= 201112L && !defined __GNUC__)
        # define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))
        #else
        # define const_cast(T, p)  (T) (p)
        #endif

> The only place programmers would notice the different prototype would be
> in function pointers, but that's where Chris's proposal N3674 would kick
> in.  It would allow unidirectional implicit conversions of functions
> where one is more restrictive than the other regarding qualifiers.

I see. Yes, then N3674 makes a lot of sense: The language would feel
incomplete if this implicit conversion from 'char **' to 'const char **'
was allowed in argument passing but not in function pointer types.

Bruno




Reply via email to