Initialization discards qualifiers from pointer target type
Asked Answered
K

2

53

I'm trying to print the list of a singly linked list that I referred to in link text. It works, but I do get the compiler warnings:

Initialization discards qualifiers from pointer target type

(on declaration of start = head) and

return discards qualifiers from pointer target type

(on return statement) in this code:

/* Prints singly linked list and returns head pointer */
LIST *PrintList(const LIST *head) 
{
    LIST *start = head;

    for (; start != NULL; start = start->next)
        printf("%15s %d ea\n", head->str, head->count);

    return head;
}

I am using XCode. Any thoughts?

Keratoid answered 23/2, 2010 at 5:47 Comment(1)
Just FYI I've had gcc print unidentified warnings like this that I think are controlled by -Wwrite-strings. There's -Wdiscarded-qualifiers, -Wcast-qual and clang's -Wincompatible-pointer-types-discards-qualifiers which look related too.Randarandal
F
93

It's this part:

LIST *start = head;

The parameter for the function is a pointer to a constant, const LIST *head; this means you cannot change what it is pointing to. However, the pointer above is to non-const; you could dereference it and change it.

It needs to be const as well:

const LIST *start = head;

The same applies to your return type.


All the compiler is saying is: "Hey, you said to the caller 'I won't change anything', but you're opening up opportunities for that."

Ferretti answered 23/2, 2010 at 5:49 Comment(4)
Dumb question, but what does a const return type look like? I tried searching on the web, and I can't seem to find one.Keratoid
@Keratoid - const LIST *PrintList(const LIST *head) { ... }Austria
The parameter for the function is a constant pointer - incorrect. const LIST *head declares head as a pointer to a constant LIST. See: c-faq.com/decl/constparm.html -- perhaps this is just a misunderstanding in the wording.Dual
Love it when it gets explained in natural language, as if the compiler could talk. Great explanation!Habitancy
O
29

In following function, would get the warning that you encountered with.

void test(const char *str) {
  char *s = str;
}

There are 3 choices:

  1. Remove the const modifier of param:

    void test(char *str) {
      char *s = str;
    }
    
  2. Declare the target variable also as const:

    void test(const char *str) {
      const char *s = str;
    }
    
  3. Use a type convert:

    void test(const char *str) {
      char *s = (char *)str;
    }
    
Ostap answered 27/5, 2013 at 14:51 Comment(1)
Good answer in my opinion. One question that I have @Ostap is about the third choice: Doesn't it prevent the aim of the const? The programmer can now change the value of str with the pointer s, doesn't he? Or we are satisfied with the fact he "delcared" about that by using the type convert (char *)str?Devastating

© 2022 - 2024 — McMap. All rights reserved.