52

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?

Community
  • 1
  • 1
Crystal
  • 28,460
  • 62
  • 219
  • 393
  • 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. – jozxyqk Oct 05 '18 at 23:00

2 Answers2

92

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."

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 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. – Crystal Feb 23 '10 at 06:00
  • 5
    @Crystal - `const LIST *PrintList(const LIST *head) { ... }` – R Samuel Klatchko Feb 23 '10 at 07:42
  • 1
    `The parameter for the function is a constant pointer` - incorrect. `const LIST *head` declares head as a pointer to a constant LIST. See: http://c-faq.com/decl/constparm.html -- perhaps this is just a misunderstanding in the wording. – CivFan Sep 17 '15 at 17:48
  • 3
    Love it when it gets explained in natural language, as if the compiler could talk. Great explanation! – Zimano Oct 27 '15 at 09:38
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;
    }
    
Eric
  • 22,183
  • 20
  • 145
  • 196
  • Good answer in my opinion. One question that I have @Eric 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`? – e.ad Dec 26 '22 at 14:40