3

Here is the code:

#include <stdio.h>

void test(const char* anagrams[])
{
    while(*anagrams != NULL) {
        printf("%s\n", *anagrams);
        anagrams++;
    }
}

int main()
{
    char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};

    printf("%lu\n", sizeof(arr));
    test(arr);
}

This code generates the following warning:

$ gcc const_char_star_star.c

const_char_star_star.c:16:8: warning: passing 'char *[8]' to parameter of type 'const    char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]

test(arr);
   ^~~
const_char_star_star.c:3:23: note: passing argument to parameter 'anagrams' here
void test(const char* anagrams[])
                  ^

1 warning generated.

If I remove the const qualifier in the arguments for test, it compiles without any warning.

haccks
  • 104,019
  • 25
  • 176
  • 264
ap2014
  • 91
  • 5
  • as a side note: it is not good practice to use the function argument as a variable like that, if the function is more complex it may make it more difficult to follow. better to declare a local variable that copies the argument and leave the original intact. optimization will anyway fix it for you under the hood. – AndersK Jul 12 '14 at 17:31
  • `printf("%zu\n", sizeof(arr));` : use `"%zu"` for `sizeof` or (`size_t`). – BLUEPIXY Jul 12 '14 at 21:49

3 Answers3

3

Duplicate of:

Double pointer const-correctness warnings in C

Answered in the C FAQ:

http://c-faq.com/ansi/constmismatch.html

Copy pasting example:

const char c = 'x';     /* 1 */
char *p1;               /* 2 */
const char **p2 = &p1;  /* 3 */
*p2 = &c;               /* 4 */
*p1 = 'X';              /* 5 */

In line 3, we assign a char ** to a const char **. (The compiler should complain.) In line 4, we assign a const char * to a const char *; this is clearly legal. In line 5, we modify what a char * points to--this is supposed to be legal. However, p1 ends up pointing to c, which is const. This came about in line 4, because *p2 was really p1. This was set up in line 3, which is an assignment of a form that is disallowed, and this is exactly why line 3 is disallowed.

Community
  • 1
  • 1
hdante
  • 7,685
  • 3
  • 31
  • 36
1

As you have pointer out yourself, it is a qualifier problem;

const char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};

adding const to the declaration makes the warning go away as well.

Soren
  • 14,402
  • 4
  • 41
  • 67
  • BTW, good job on paying attention to `warnings` -- they are more important that they sometimes appear. – Soren Jul 12 '14 at 17:23
0

A keyword const indicates that the value which the variable holds cannot be changed. here

char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};  
test(arr);

and the function test is defined as

void test(const char* anagrams[])

Which indicates the value to which the pointer points cannot be changed,so that the function cannot change the original values of the array.

The compiler generates warning because while calling the function test(arr); it not specified that the array 'arr' is a const two dimensional array ,which creates ambiguity since a char* array used in main function is passed as a const char* to the compiler and hence generates a warning as you've specified.

Inoder to avoid warning declare the array as

const char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};

Sorcrer
  • 1,634
  • 1
  • 14
  • 27
  • Thank you for the explanation. My intent was not to define the arr as const but the function test should not be allowed to modify that. What is the right way of doing that ? – ap2014 Jul 14 '14 at 16:40