ap2014
ap2014

Reputation: 91

c compiler warning when passing a char *arr[] to a function as const char **arr

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.

Upvotes: 3

Views: 1580

Answers (3)

Sorcrer
Sorcrer

Reputation: 1644

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};

Upvotes: 0

hdante
hdante

Reputation: 8020

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.

Upvotes: 3

Soren
Soren

Reputation: 14688

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.

Upvotes: 1

Related Questions