Linker errors

The compiler makes assumptions

In a previous lecture, we have seen that the compiler makes an assumption for functions that have no prototype (i.e the function returns an int).

When we compile with the -c switch as in


gcc -c -Wall -ansi hello.c
we are telling the compiler not to invoke the linker.

Therefore, the compiler assumes that any function which is used in hello.c but not declared in hello.c will be found in some other file.

What's the linker do

It's the linkers job to "resolve" the location of functions that the compiler couldn't find.

But what if the linker can't find the function either?

If the linker can't find the function in any of the .o files or libraries, it generates an error known as "undefined reference". An executable file cannot be produced.

findstats.c revisited

Here's a slightly modified version of findstats.c.
The function call to Sum(a,b) has been changed to sum(a,b).

/********************************************
* File: findstats.c
* Author: S. Bogar
* Date: 8/3/99
* Section 101
* EMail: bogar@cs.umbc.edu
*
* This file contains the main program which gets two
* integers from the user and then reports statistics
* about these integers.  
*
* This file makes use of functions found in a 
* separately-compiled object file.
*********************************************/

#include <stdio.h>

/* stats.h contains function prototypes */
#include "stats.h"

int main ()
{
   int a, b ;

   /* get two ints from user */
   printf("Enter first number: ") ;
   scanf ("%d", &a) ;
   printf("Enter second number: ") ;
   scanf ("%d", &b) ;
   printf("\n") ;

   /* call arithmetic functions and print results */
   printf("The sum of %d and %d is: %d\n",
           a, b, sum (a, b) ) ;
   printf("The smaller of %d and %d is: %d\n",
           a, b, Min (a, b) ) ;
   printf("The larger of %d and %d is: %d\n",
           a, b, Max (a, b) ) ;
   printf("The average of %d and %d is: %f\n",
           a, b, Avg (a, b) ) ;
   printf("The distance between %d and %d is: %d\n",
           a, b, Dist (a, b) ) ;

   /* we're done !! */
   printf("That's all folks.\n") ;

   return 0;
}
The functions in stats.c haven't been changed.

/********************************************
* File: stats.c
* Author: S. Bogar
* Date: 8/3/99
* Section 101
* EMail: bogar@cs.umbc.edu
*
* This file contains some simple statistical
* functions each written to handle two integers
* as input.  They are grouped together in this 
* file because they are related modules, all simple
* statistical functions, and as such could be used
* by any program that deals with simple statistics
* involving only two integers.
* 
* This file is meant to be compiled separately from 
* the main program.
*
* Functions in this file:
*    Sum (x, y)
*    Min (x, y)
*    Max (x, y)
*    Avg (x, y)
*    Dist (x, y)
*
*********************************************/

/***********************************
 * All header files needed by the code 
 * found in the functions defined
 * in this file.  NOTE: Since none of
 * these functions do input or output, 
 * there is no need to #include 
************************************/
#include "stats.h"


/********************************************
* Function: Sum
* Usage:    z = Sum (x, y)
*
* This function adds the two values passed in
* and returns their sum.
*
* Input: two integers to be added
* Output: Returns the sum of x and y.
*********************************************/
int Sum (int x, int y) {
   int sum ;

   sum = x + y ;

   return sum ;
}

/*********************************************
* Function: Max 
* Usage:    z = Max (x, y)
*
* This function determines which of the values
* passed in is larger.
*
* Inputs: two integers to be compared
* Output: Returns the larger of x and y.
*********************************************/
int Max (int x, int y) {
   int max ;

   if (x > y) {
      max = x ;
   } else {
      max = y ;
   }

   return max ;
}


/*********************************************
* Function: Min
* Usage:    z = Min (x, y)
*
* This function determines which of the values
* passed in is smaller.
*
* Inputs: two integers to be compared
* Output: Returns the smaller of x and y.
*********************************************/
int Min (int x, int y) {
   int min ;

   if (x < y) {
      min = x ;
   } else {
      min = y ;
   }

   return min ;
}

/*********************************************
* Function: Avg
* Usage:    z = Avg (x, y)
*
* This function calculates the average of the
* two values passed in.
*
* Inputs: two integers to be compared
* Output: Returns average of x and y as a 
*         *** double ***
*********************************************/
double Avg (int x, int y) {
   double average ;
 
   average = (x + y) / 2.0 ;

   return average ;
}


/*********************************************
* Function: Dist 
* Usage:    z = Dist (x, y)
*
* This function calculates the distance between
* x and y on a number line.
*
* Input: two integers for which distance is calculated
* Output:Returns the absolute value of x - y.
*********************************************/
int Dist (int x, int y) {   
   int distance ;

   distance = x - y ;
   if (distance < 0) {
      distance = -distance ;
   }

   return distance ;
}

Now let's compile and see what happens


linux2[113] % ls
big.c  findstats.c  stats.c  stats.h
linux2[114] % gcc -c -Wall -ansi findstats.c
findstats.c: In function `main':
findstats.c:31: warning: implicit declaration of function `sum'
linux2[115] % gcc -c -Wall -ansi stats.c
linux2[116] % gcc -Wall -ansi findstats.o stats.o
findstats.o: In function `main':
findstats.o(.text+0x58): undefined reference to `sum'
collect2: ld returned 1 exit status
linux2[117] % ls
big.c  findstats.c  findstats.o  stats.c  stats.h  stats.o
linux2[118] % 

Notice that the compiler gave us a warning, but threw no errors. It assumed that the function "sum" would be found by the linker in some other .o or library file. When the linker didn't find the function "sum", it reported the "undefined reference". So even though the two .o files were produced the linker cannot make the executable file, a.out

The most frequent cause of this error is simply misspellling the name of your function.

Last modified -