Thread: Little warning on linked lists example

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    158

    Little warning on linked lists example

    Hi there.

    Following my latest thread about queues, someone suggested me something to my code that I decided to also implement it on my linked-lists example but it gives me a warning. Though, it compiles and works...

    Here's the code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAX 10
    
    typedef struct sList {
    	int elem;
    	struct sList *next;
    } List;
    
    List* insertList(List *l, int elem) {
    	if(!l) {
    		List *x = (List*)malloc(sizeof(List));
    		
    		x->elem = elem;
    		x->next = NULL;
    		
    		return x;
    	} else {
    		l->next = insertList(l->next, elem);
    		
    		return l;
    	}
    }
    
    void printList(const List *l) {
    	List *ptr = l; // warning: initialization discards qualifiers from pointer target type
    	
    	do {
    		printf("%d", ptr->elem);
    		ptr = ptr->next;
    		
    		if(ptr) printf(" -> ");
    	} while(ptr);
    }
    
    int main() {
    	List *l = NULL;
    	int i, num;
    	
    	srand((unsigned)time(NULL));
    	
    	printf("RANDOM: ");
    	
    	for(i = 0; i < MAX; i++) {
    		num = rand() % 100 + 1;
    		printf("%d ", num);
    
    		l = insertList(l, num);
    	}
    
    	printf("\n\nLIST: ");
    	printList(l);
    	
    	return 0;
    }
    There's only one line with a comment which is the line that produces the warning and the comment itself is the warning.

    What does it mean and how can I get rid of it?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    l is const while ptr is declared as non-const.
    You should make ptr const: const List* ptr = l;
    Const is there to catch mistakes; you shouldn't do away with it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    But in the queues thread where you suggested me to do that, I didn't had const to ptr and it didn't produce any warning. That's why I'm asking...

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Does the function printList require a non-const pointer? No, because it does not modify any data; thus your const is correct and ptr should be const too!
    I think you may have gotten this a little backwards.
    If the function printList DID modify the memory at the pointer, then it shouldn't take a const pointer in the first place!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    You are confusing me...

    I just add the const like you said before just to prevent the compiler from compiling if in that function the memory was being modified and I didn't want that. And in the queues example, the memory was being modified so I add the const to the function argument but I didn't add it to the ptr and it worked without any warning.

    The printList function is not modifying the memory, so, should I just remove the const?

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    OK, so let me repeat:
    - Const will help you find mistakes.
    - If const is applies to a pointer, the compiler will spew an error if you try to modify the memory pointed to by the pointer.
    - If a function is not supposed to modify the pointer pointed to by a pointer, then that pointer should be const.

    So think before you design something... is this function supposed to modify memory pointed to by the pointer? If the answer is no, then it should take a const pointer. But you must keep the const intact in the whole function.
    If you do
    Code:
    void foo(const int* p)
    {
    	*p = 70;
    }
    
    void foo2(const int* p)
    {
    	int* n = p;
    	*n = 70;
    }
    First example won't work because p is const. Second will work because you're doing away with the const which is obviously wrong.
    The solution is to make n const too --> const int* n = p;
    If a function takes a const pointer, then you must declare every other pointer const that you're assigning that address from the const pointer.

    Your function printList should take a const pointer because it's not modifying any memory. Similarly, your local variable ptr must also be const, otherwise it's the same result as if the function wasn't taking a const variable at all!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    But why on my queues example I only have to add const the the function argument and not to the local variable ptr as in the printList example?

    Both functions are not modifying any memory, so, both should take a const pointer like you said and similarly, like you also said, the local varible ptr must also be const. I think this applies to both functions (printQueue and printList) because both are not modifying any memory.

    So, you are saying that also on the printQueue function I should add const to the function argument and local variable ptr?

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    First example won't work because p is const. Second will work because you're doing away with the const which is obviously wrong.
    I am less familiar with const in C, but I believe both will not work. const int* p means that what p points to is const, not p itself. int* const p on the other hand, means that p is const.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    I am less familiar with const in C, but I believe both will not work. const int* p means that what p points to is const, not p itself. int* const p on the other hand, means that p is const.
    Oh, the second one works alright.
    The first one doesn't. You can check with your c compiler

    Quote Originally Posted by Nazgulled View Post
    But why on my queues example I only have to add const the the function argument and not to the local variable ptr as in the printList example?
    I can't remember from the top of my head, but here's the thing - as seen from my second example, if you don't add const to your local pointer and assign the address from the const pointer, then you're effectively removing the const. So then what's the use of const in the first place? Remember that the function SHOULD take a const pointer because it doesn't modify the memory it holds.
    So in that case, ptr must be const.
    However, if you are assigning memory to ptr from a source that is NOT const (in your case, that would be anything but l), then it can or can not be const. If you promise never to change the data it points to after assigning it, then yes, it should be const too, to be 100% correct.

    Both functions are not modifying any memory, so, both should take a const pointer like you said and similarly, like you also said, the local varible ptr must also be const. I think this applies to both functions (printQueue and printList) because both are not modifying any memory.
    Exactly.

    So, you are saying that also on the printQueue function I should add const to the function argument and local variable ptr?
    If they do not modify memory, then yes.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Oh, the second one works alright.
    Ah, so gcc 3.4.5 only complains with a warning, though g++ 3.4.5 reports an error. I still do not recommend talking about const pointers when you mean pointers to const. Naming iterators to const const_iterator in the C++ standard library was a mistake, no need to propagate it to C as well.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Hmmm. "ptr is const" and "l is a pointer to const".
    Is that better definition?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 07-10-2008, 03:45 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM