Thread: Invalid conversion from 'const void*' to 'void*' error

  1. #1
    Prawntoast
    Join Date
    Apr 2005
    Posts
    3

    Invalid conversion from 'const void*' to 'void*' error

    Hi

    I am having problems comiling the following code

    List Header file

    // list.h - Linked List ADT

    Code:
    #ifndef _LIST_H_
    #define _LIST_H_
    struct List;
    typedef struct ListNode *Position;
    List *ListConstruct();  // NULL if fails
    void ListDestroy(List *l);
    bool ListEmpty(const List *l);
    Position ListHead(const List *l);
    Position ListFirst(const List *l);
    Position ListNext(const List *l, Position p);
    Position ListLast(const List *l);
    Position ListAdvance(const List *l, Position p);
    Position ListPrevious(const List *l, Position p);
    void *ListRetrieve(const List *l, Position p);
    bool ListInsert(List *l, Position p, void *item);
    void ListDelete(List *l, Position p);
    typedef void ListCallback(const void *);
    void ListTraverse(const List *l, ListCallback *fn, bool fwd);
    #endif
    Program to insert info into list

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include "list.h"
    
    //the callback function
    void printname(void *ptr) {
    	printf("%s\n", (char *)ptr);
    }
    
    int main() {
    		List *l;
    		Position p;
    
    		if  ((l = ListConstruct()) == NULL) {
    		exit(EXIT_FAILURE);     //unable to create list
    	}
    	p = ListHead(l); // start at front of enpty list
    	
    	//insert an item at the front
    	if (!ListInsert(l,p, "Freddy")) {
    		exit(EXIT_FAILURE);
    	}
    	//insert another item after that - move position first
    
    	p = ListNext(l,p);
    	if (!ListInsert(l, p, "Billy")) {
    		exit(EXIT_FAILURE);
    	}
    
    	//now insert a third one before the last
    	if (!ListInsert(l, p, "Johnny")) {
    		exit(EXIT_FAILURE);
    	}
    
    	//Finally the last one at the end
    	p=ListLast(l);
    	if (!ListInsert(l, p, "Mickey")) {
    		exit(EXIT_FAILURE);
    	}
    
    	// Now print out the list in the forward direction
    
    	ListTraverse(l, printname, true);
    
    	//destroy the list before finishing
    	ListDestroy(l);
    	return 0;
    }
    I am getting the following compile errors

    namelists.c: In function `int main()':
    namelists.c:20: invalid conversion from `const void*' to `void*'
    namelists.c:26: invalid conversion from `const void*' to `void*'
    namelists.c:31: invalid conversion from `const void*' to `void*'
    namelists.c:37: invalid conversion from `const void*' to `void*'
    namelists.c:43: invalid conversion from `void (*)(void*)' to `void (*)(const void*)'

    I am assuming the reason for this is something to do with pointers, but I am at a bit of loss as to what to do as we haven't been provided with many examples.

    Could someone explain why I am getting this error

    Thanks

    PT

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    One is a type mismatch and the other is an issue with stripping an implied const qualifier. Let's look at the last error first.

    >invalid conversion from `void (*)(void*)' to `void (*)(const void*)'
    const is a funny beast. Look at your definition of printname:
    Code:
    void printname(void *ptr) {
    Now, printname is passed to ListTraverse, which is declared as:
    Code:
    void ListTraverse(const List *l, ListCallback *fn, bool fwd);
    ListCallback is in turn typedef'd as:
    Code:
    typedef void ListCallback(const void *);
    Notice the const qualifier. Your compiler doesn't like that you're passing a function with a different signature, even if the only difference is const.

    Now for the other errors.

    >invalid conversion from `const void*' to `void*'
    This is tricky, and also an issue with const qualification. Now, IIRC this shouldn't be an issue, but since you're passing a string literal to ListInsert, ListInsert should expect a const void*. That only makes sense anyway since you're likely making a copy of the argument for your list.
    My best code is written with the delete key.

  3. #3
    Prawntoast
    Join Date
    Apr 2005
    Posts
    3
    Thanks for your response.

    It makes sense to me that have to match so I have changed the printname and ListInsert to use a const void * type and that elimated the errors but created a new one in ListInsert function.

    Here is the code for that.
    Code:
    bool ListInsert(List *l, Position p, const void *item) {
        ListNode *tmp;
    
        tmp = (ListNode *)malloc(sizeof(ListNode));
        if (tmp == NULL) {
            return false;  // No memory
        }
        tmp->item = item;
        if (p == NULL) { // insert at head
            tmp->next = l->head;
            l->head = tmp;
        }
        else {
            tmp->next = p->next;
            p->next = tmp;
        }
        return true;
    }
    The line reporting the error is

    Code:
    tmp->item = item;
    would this mean i would need to change void *item to const void *item

    I think I am a bit stumped on the usage of const.

    Thanks Again for you help.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >would this mean i would need to change void *item to const void *item
    No, it would mean that you've located a logic error by being const-correct. When you assign pointers, you do just that, assign the pointer. The memory the pointers refer to remains the same, so you have two pointers that refer to the same memory. If your driver looked like this then all of your nodes would have the same contents because they all point to buffer:
    Code:
    int main ( void )
    {
      List *list;
      char buffer[BUFSIZ];
    
      if  ( ( list = ListConstruct() ) == NULL )
        return EXIT_FAILURE;
    
      while ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
        if ( !ListInsert ( list, ListHead ( list ), buffer ) )
          break;
      }
    
      ListTraverse ( list, printname, true );
      ListDestroy ( list );
    
      return 0;
    }
    I also get the feeling that you're compiling as C++ instead of C. Mostly because bool isn't a valid C type for the code you've given. You also don't need to cast the result of malloc in C.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quantum Random Bit Generator
    By shawnt in forum C++ Programming
    Replies: 62
    Last Post: 06-18-2008, 10:17 AM
  2. Avoiding Global variables
    By csonx_p in forum Windows Programming
    Replies: 32
    Last Post: 05-19-2008, 12:17 AM
  3. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  4. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  5. using c++ in c code
    By hannibar in forum C Programming
    Replies: 17
    Last Post: 10-28-2005, 09:09 PM