why am I getting an undefined reference error in C for my implementation of a singly linked list-Collection of common programming errors

I am getting an error that reads like this

$ gcc -o app llistdriver.c llistlib.c -Wall
 llistdriver.c:7: warning: return type defaults to `int'
 llistdriver.c: In function `printinsts':
 llistdriver.c:15: warning: control reaches end of non-void function
 llistlib.c: In function `insert':
 llistlib.c:25: warning: statement with no effect
 llistlib.c:41: warning: control reaches end of non-void function
 /tmp/ccqYmK3M.o:llistdriver.c:(.text+0x157): undefined reference to `_search'
 collect2: ld returned 1 exit status

and I cannot figure out why I am getting this error message have written a library file that contains the methods for the linked list.

  int search( struct node *front, int val)// 
 {
     while(front != NULL)
    {
       if( front->modmark == val ) //this is to find the value 
       return 1;  // found it

    front=front->next;
    }
    return 0;  // Not found
  }

I assume that it is complaining about the only reference in the main file

        case 5: 
                printf("please enter a search value?\n");
                scanf("%i",&mark);
                choice = search(first,mark);//here
                if (choice == -1)
                {

                    printf("the modmark was not found\n");
                }
                else 
                {   
                    printf("the first occurence of the mark is at the %i th index of the list",choice); 
                };
                    break;

and first and mark are variables that are defined like this

                 struct node *first;
              int mark = 0;

any help on this would be much appreciated I have spent hours trying to debug this error. Writing C code is of the the banes of my life at the moment.

Ps I have checked all the #include “llistlib.h” there are included in the llistlib.c file and the llistdriver.c file.

Ok maybe this will make it much clearer

// llistlib.c – the library which implements the functions defined in the listlib.h file #include #include #include “llistlib.h”

void initialise(struct node **ps)
{

printf("initialise function\n");

*ps = NULL;   //initialise list to empty

}


int insert(struct node **fn)
{
printf("insert function\n");
struct node *newnode;
newnode =  (struct node*) malloc(sizeof (struct node)); //make new node and give it memory
if (newnode == NULL) //if fsiled return to the program saying it failed
    return -1;
if (*fn == NULL) // for the first of the list
{
    newnode -> next == NULL; // sets the next value to nothing
    printf("what mark do you want to enter\n");
    scanf("%i",&newnode -> modmark); // this gets the modmark
    *fn = newnode; //the head of the list is set to the new node
}
else
{
    newnode -> next = *fn; // sets the newnodes next value to the head node
    printf("what mark do you want to enter\n");
    scanf("%i",&newnode -> modmark); // gets the modmark
    *fn = newnode; // the head becomes the new node


    printf("%p %i",newnode,newnode->modmark); // just for debugging

}
 }



void traverse(struct node *ps)
{   

if (ps != NULL) // if the current node is null 
{
    printf("%p - %i\n",ps,ps -> modmark);
    traverse(ps -> next); 

}
else
{
    printf("your list is empty\n");
}
}


void delete(struct node **dn)
{
printf("delete function\n");
struct node *delnode;
delnode = *dn; //sets the head node so that it can be deleted later
if (delnode != NULL)
{
    *dn = delnode -> next; // sets the head to the next node
    free(delnode); //deletes the previous head node
}

}


void finish(struct node **ps) //this function goes through the list and removes all items
{
printf("finish function\n");
struct node *finishnode;
finishnode = *ps;
while (finishnode != NULL)
{
    *ps = finishnode -> next;
    free(finishnode);
    finishnode = *ps;
}

int search(struct node *front,int val)
{
 while(front != NULL)
 {
    if( front->modmark == val ) // Assuming struct node has val member which you are trying to compare to
       return 1;  // found it

    front=front->next;
 }
  return 0;  // Not found
}

}

and then the llistdriver.c file is

#include 
#include 
#include "llistlib.h"


printinsts()
{
printf("Enter:- \n");
printf("\t0 to exit\n");
printf("\t1 to initialise list\n");
printf("\t2 to insert item at front of list\n");
printf("\t3 to delete item from front of list\n");
printf("\t4 to traverse list\n");
printf("\t5 to search through the list\n");
}




int main()
{
int choice;
struct node *first;
int mark = 0;

printinsts();
scanf("%d",&choice);

while (1)
{
    switch (choice)
    {
        case 0 : finish(&first);
                    exit(0);
                    break;

        case 1 : initialise(&first);
                    break;

        case 2 : if (insert(&first)== -1)
                    {
                        printf("insert not successful");
                        choice = 0;
                     };
                    break;

        case 3 : delete(&first);
                    break;

        case 4 : traverse(first);
                     break;
        case 5: 
                printf("please enter a search value?\n");
                scanf("%i",&mark);
                choice = search(first,mark);
                if (choice == -1)
                {

                    printf("the modmark was not found\n");
                }
                else 
                {   
                    printf("the first occurence of the mark is at the %i th index of the list",choice); 
                };
                    break;

        default : printf("Invalid choice of %d \n", choice);

    };  // end of switch

    printinsts();
    scanf("%d", &choice);

}  // end of while

}

and the header file llistlib.h reads as

struct node {
int     modmark;
struct node *next;
 };


void initialise(struct node **ps);


int insert(struct node **fn);


void traverse(struct node *ps);


void delete(struct node **dn);


void finish(struct node **ps);


int search(struct node *front,int val);

I havent been able to spot a obvious problem among any of the code yet

  1. Your finish function is missing a closing brace {. And search has an extra closing brace.

  2. Just include llistlib.h in your llistlib.c file as follows:

    #include "llistlib.h"

    and use folloeing command for compilation:

    gcc -o app llistdriver.c llistlib.c

    Hope this helps…

  3. First error:

     llistdriver.c:7: warning: return type defaults to `int'
     llistdriver.c: In function `printinsts':
     llistdriver.c:15: warning: control reaches end of non-void function
    

    The function looks like:

    printinsts() {}
    

    Please give this function a return type, and if it’s not void, return it.

    Secondly:

    llistlib.c: In function `insert':
    llistlib.c:25: warning: statement with no effect
    

    That line is:

    newnode -> next == NULL; // sets the next value to nothing
    

    The comment is not true, this line does not set anything, as it uses the equality operator, not the assignment operator.

    (it’s partly a matter of taste, but I don’t like comments like these, which simply try to state the same thing as the code itself. In cases like these, they become misleading, as you may read, and believe, the comment, rather than parsing the code when looking for a bug.)

    Then:

    llistlib.c:41: warning: control reaches end of non-void function
    

    Which again refers to:

    int insert(struct node **fn)
    {
    printf("insert function\n");
    struct node *newnode;
    newnode =  (struct node*) malloc(sizeof (struct node)); //make new node and give it memory
    if (newnode == NULL) //if fsiled return to the program saying it failed
        return -1;
    ...
    }
    

    There are no returns from this function other than that -1. It should return something no matter what happens.

    Lastly:

    /tmp/ccqYmK3M.o:llistdriver.c:(.text+0x157): undefined reference to `_search'
    

    Because you missed a closing brace from the end of finish();

    Do NOT ignore warnings just because your code compiles. Fixing just the errors is not enough!

  4. You are compiling with the default GCC setting, which is “roughly follow the C99 standard, then add non-standard GNU goo”. The C99 standard, as well as the current C standard, do not allow functions to have a default type. That is why you get a warning with -Wall, the return type must be explicit.

    printinsts() {} is not valid C. You should declare/define this as void printinsts (void) and nothing else.

    In the future, make sure to always compile with -std=c99 or -std=c11, to ensure that you are compiling the code as standard C language and not something else.

Originally posted 2013-11-27 12:01:31.