3

I have the following situation:

A function creates an array of strings and then passes this to a bunch of other functions. These other functions should not modify neither pointers pointed to by the outer pointer nor the strings themselves, so I made them const.

Minimal example:

void function(const char * const *arr) {
    /* Do something useful */
}

int main(void) {
    char **x;
    /* fill x and *x */
    function(x);
}

When compiling with gcc or clang this gives me a warning, that x is converted to an incompatible pointer type.

While I understand why the pointer type is incompatible if I remove the second const in the parameter list of function (explained here: Why does passing char** as const char** generate a warning?), I do not understand why it is incompatible with the const.

Compiling with a c++-Compiler does not give me the warning (See comparison here: https://gcc.godbolt.org/z/YND5U7)

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
urzeit
  • 2,863
  • 20
  • 36
  • 2
    You should mention the command line arguments used for compiling. However, I fiddled a bit in godbolt with your sample: [**Comparison in godbolt**](https://gcc.godbolt.org/z/YND5U7). I can confirm your observation. (You may use it in your question if you like.) It looks like whether C does type-check stricter than C++ in this case. (Usually, it's vice versa, isn't it?) :-) – Scheff's Cat Jan 04 '19 at 06:40
  • Also see https://stackoverflow.com/questions/28701376/incompatible-pointer-types-and-constness – Support Ukraine Jan 04 '19 at 06:50
  • Also see https://stackoverflow.com/questions/41180809/gcc-issues-warning-of-incompatible-pointer-type – Support Ukraine Jan 04 '19 at 06:51
  • Actually it's not a duplicate. The referenced question asks for `char**` -> `const char **`. I asked for `char**` -> `const char * const *` – urzeit Jan 04 '19 at 07:04
  • @urzeit Hmm, ok - I removed the dup but I still think the answer is the same as the provided links – Support Ukraine Jan 04 '19 at 07:22
  • @4386427: I don't think so. The reason why `char **` -> `const char **` is dangerous does not apply with the second const, since the pointed to pointer cannot be modified. – urzeit Jan 04 '19 at 07:33
  • Would you mind adding the actual warning you got? – Ulrich Eckhardt Jan 04 '19 at 07:46

1 Answers1

1

I do not understand why it is incompatible with the const.

Note: const1, const2 defined for clarity to distinguish the two.

In C, the const2 in const1 char * const2 *arr is the qualifier x optionally matches. const2 say that function(const1 char * const2 *arr) has a contract with the calling code, it will not change what arr points to. arr points to a const1 char *. arr can be const1 char ** or const1 char * const2 *.

In main(), incompatible because *x points to a char * and not a const1 char *. What it points to is different than what function() expects. const1 is not part of the function() no-write contract. Instead, const1 char * is a type and that differs from char *.

At this point, I see no reason why C could not have been specified differently to allowed a char * to be treated like a const1 char * in function() - it is simply a case that C does not allow it.

#define const1 const
#define const2 const
void function(const1 char * const2 *arr) {
    // Do something useful
}

int main(void) {
    char **x = 0;
    function(x);  // bad  
    // note: expected 'const char * const*' but argument is of type 'char **'

    const char **x2 = 0;
    function(x2); // OK
}

No comment on C++

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256