cgccconstantscompiler-warningsglibc

Should I care about Wcast-qual errors?


I recently read the NASA's power of 10 rules, and thought the rule about "using the compiler's most pedantic setting" was very interesting, considering warnings exist for a reason. I already previously used -Wall -Wextra, but then I also added:

-Wpedantic -Wsign-conversion -Wcast-qual -Wfloat-equal -Wswitch-default -Wduplicated-branches -Wduplicated-cond

I am currently doing a C course (42) that makes you re-create part of the libc library, and had a bunch of warnings pop up in my library. My question is about this warning in particular from Wcast-qual:

Warning: cast discards ‘const’ qualifier from pointer target type

See the below code snippet:

void    *ft_memchr(const void *ptr_void, uint8_t byte, size_t length)
{
    const uint8_t   *ptr = (const uint8_t *) ptr_void;

    while (length > 0)
    {
        if (*ptr == byte)
            return ((void *) ptr); // Warning here
        length--;
        ptr++;
    }
    return (NULL);
}

Is there any value to having a const return parameter? I know that having const parameters signals to the function that you will not change its value, allowing the compiler to optimize certain things but if I do this for the return, is there any value gained?

It seems to me that if I change my return type to be const void to avoid this warning, all I'm doing is shifting the warning from the function side to the caller's side, because to use this memchr result, the person will need to cast away the const qualifier.


Solution

  • You should absolutely care about const-correctness and casting away the const is one of the most dangerous things you can do. The const prevents any modification of the pointed-to object, without the const you don't have the compiler protect you against Undefined Behavior.

    const int i = 3;    // May reside in read-only memory
    const int* p = &i;  // Safe, compiler prevents from modification
    int* m = (int*) p;  // Unsafe, no compiler protection
    *m = 4;             // UB
    

    You may not always have the choice when interacting with foreign code that does not use const, and in that case a cast may be your only option (other than potentially very expensive copy). If so, I would recommend silencing the warning on just that single line, with comment quoting some documentation that the function pinky promises to treat the pointer as const, even if not marked as such.

    Here, the memchr is arguably badly defined and should have two names overloads, one taking and returning const void* and the other taking and returning void*. C23 fixes this issue in a similar way.