Search code examples
arrayscpointersconstants

Avoiding GCC compiler "incompatible pointer type" warnings


I've written two functions. One for copying an array of char type:

void char_arr_copy(const char *src, char *dst, int arr_size)
{
    int i;
    for (i=arr_size-1; i >= 0; src++, dst++, i--)
        *dst = *src;
}

and another for copying an array of char addresses:

void word_arr_copy(const char **src, char **dst, int arr_size)
{
    int i;
    for (i=arr_size-1; i >= 0; src++, dst++, i--)
        *dst = *src;
}

I think that this is an important thing to show to a future program reader in a function header that the function is not going to change the content of some addresses it operates with.

And while the first function compiles fine compiling the second one causes the following warnings:

revert_str_input_arr2.c:30:14: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   30 |         *dst = *src;
      |              ^
revert_str_input_arr2.c: In function ‘create_new_word’:
revert_str_input_arr2.c:44:23: warning: passing argument 1 of ‘word_arr_copy’ from incompatible pointer type [-Wincompatible-pointer-types]
   44 |         word_arr_copy(*word_arr_ptr, tmp, word_arr_size-1);
      |                       ^~~~~~~~~~~~~
      |                       |
      |                       word {aka char **}
revert_str_input_arr2.c:26:33: note: expected ‘const char **’ but argument is of type ‘word’ {aka ‘char **’}
   26 | void word_arr_copy(const char **src, char **dst, int arr_size)
      |                    ~~~~~~~~~~~~~^~~

As I understand one can't equate const address and address and this is the source of all of my warnings. That's a pity, cause I could do exactly the same in my first function with const char and char.

So the only way to fix this is to omit the const identifier, right?

So it turns out that I can show (to a potential future program reader) that I'm not going to change the src content only in one of my functions and in another I can't do it in any way?


Solution

  • const char **src The "const correctness" here sits with the (pointer to) pointed-at item, a const char. If you instead intended the array of pointers to be const correct, then:

    void word_arr_copy (char*const* src, char** dst, int arr_size)
    

    Read these right-to-left: "pointer to read-only pointer to char".

    However, consider this improvement instead:

    void word_arr_copy (int arr_size, char* dst[arr_size], char*const src[arr_size])