Search code examples
ccasting

Casting Const to non Const in c


I'm working on a school project in which I need to reproduce many of the C library functions. I'm just struggling with one specific aspect of it.

If you look at the man page for memchr you will see that it takes a const void * as input and returns a plain void *. I would assume that somewhere in the function they are casting from const to non const for the return variable.

However, when I do this (clang -Weverything +Werror) it won't compile. It works without the -Weverything tag but I would prefer to use it if possible anyway.

Is there any "correct" way to do this?


Solution

  • This hack will do it. In practice sizeof(void *) is equal to sizeof(size_t) on every but the most obscure platforms. Nevertheless, I'd advise against using this. You should drop -Weverything instead. Standard C functions date back as far as 70', and the initial C compilers were much less strict than today's Clang or GCC with all of the warnings enabled. The fact that you'll find something "unsafe" in some of them is unavoidable.

    void * memchr_(const void * ptr_, int c, size_t num);
    
    int main(void)
    {
        unsigned char ary[] = { 1, 6, 2, 45, 23, 75, 23, 43, 23 },
                      * ptr = NULL;
    
        ptr = memchr_(ary, 23, sizeof(ary) / sizeof(ary[0]));
        printf("ary = %p, ptr = %p, *ptr = %u\n", (void *)ary, (void *)ptr, *ptr);
        return 0;
    }
    
    void * memchr_(const void * ptr_, int c, size_t num)
    {
        size_t i;
        const unsigned char * ptr = ptr_;
    
        for(i = 0; i < num; i++) {
            if(ptr[i] == (unsigned char)c) {
                /* Casting to size_t first so that the compiler doesn't complain */
                return (unsigned char *)(size_t)ptr + i;
            }
        }
        return NULL;
    }