Note that there are some explanatory texts on larger screens.

plurals
  1. POConfused when I should and shouldn't use "const" in C
    primarykey
    data
    text
    <p>I have a dictionary that goes like this:</p> <pre><code>typedef struct dictNode { int key; char *value; struct dictNode *next; } Dict; </code></pre> <p>And a <strong>get()</strong> function that goes like this:</p> <pre><code>char *get(const Dict *dict, int key) { if(!dict) return NULL; Dict *currPtr = dict; while(currPtr) { if(currPtr-&gt;key == key) { return currPtr-&gt;value; } currPtr = currPtr-&gt;next; } } </code></pre> <p>Compiling this code produces the following error:<br> <strong>dict.c:85: warning: initialization discards qualifiers from pointer target type</strong></p> <p>This warning refers to the line:</p> <pre><code>Dict *currPtr = dict; </code></pre> <p>If I add a "const" before that line like this:</p> <pre><code>const Dict *currPtr = dict; </code></pre> <p>The warning goes away...</p> <p><strong>1)</strong> First thing I don't understand is this: I added "const" to the <strong>dict argument</strong> in <strong>get()</strong> so that the compiler warns me if I try to change the address dict is pointing to, otherwise I won't be able to access the dictionary in the main program cause I lost the address I was pointing too. Now, I'm creating a new pointer, <strong>currPtr</strong>, that points to the same place as <strong>dict</strong>. This way, I use this pointer instead, to traverse the dictionary and keep <strong>dict</strong> pointer intact. Why do I also need to have <strong>const</strong> for <strong>currPtr</strong>?</p> <p><strong>2)</strong> Second thing I don't understand is this: The line <strong>currPtr = currPtr->next;</strong> is changing the <strong>currPtr</strong> pointer, so, why doesn't the compile warn me about that if I added a <strong>const</strong> to <strong>currPtr</strong>?</p> <p>Then I have a <strong>del()</strong> function that goes like this:</p> <pre><code>Dict *del(const Dict *dict, int key) { if(!dict) return NULL; Dict *currPtr = dict; Dict *prevPtr = dict; while(currPtr) { if(currPtr-&gt;key == key) { prevPtr-&gt;next = currPtr-&gt;next; free(currPtr); } prevPtr = currPtr; currPtr = currPtr-&gt;next; } return dict; } </code></pre> <p><em>Please note that I'm aware that this delete function code is not complete, it does not correctly work if I want to delete the first element for instance. It doesn't matter, I'll finish later, it suffices to demonstrate my problem...</em></p> <p><strong>3)</strong> So, in the <strong>get()</strong> function I needed to add <strong>const</strong> to <strong>currPtr</strong> but in this <strong>del()</strong> function, I don't need to add <strong>const</strong> to <strong>currPtr</strong> nor <strong>prevPtr</strong>? In both functions I am changing the <strong>currPtr</strong> pointer and in the case of the <strong>del()</strong> function I'm changing the <strong>prevPtr</strong> pointer too. Why does the <strong>get()</strong> function require me to add a <strong>const</strong> before <strong>currPtr</strong> and the <strong>del()</strong> function does not require me to add a <strong>const</strong> before <strong>currPtr</strong> and <strong>prevPtr</strong>?</p> <p>I can basically resume this whole post to: When and where exactly in my <strong>get()</strong> and <strong>del()</strong> functions should I use <strong>const</strong> and why, and, when and where I shouldn't?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload