简体   繁体   中英

My C program is not compiling, undefined reference to 'compare"

I am trying to compile these four files by using the make command. Here are the four files

makefile

# target : dependencies
program1 : main.o org_fun.o comp_fun.o print_fun.o
      gcc main.o org_fun.o comp_fun.o print_fun.o -Wall -o program1
 
main.o : main.c
      gcc -c main.c -Wall
 
org_fun.o : org_fun.c
      gcc -c org_fun.c -Wall
 
comp_fun.o : comp_fun.c
      gcc -c comp_fun.c -Wall
 
print_fun.o : print_fun.c
      gcc -c print_fun.c -Wall

main.c

//declare libraries
  #include <string.h>
  #include <stdio.h>
  #include <stdlib.h>
 
  //declare other functions/files to be used in the program
  void org_fun(int arg, unsigned char networks[arg][4],
              int *net_size_A, int *net_size_B,
              int *net_size_C, int *elemA, int *mostA,
              int *mostB, int *elemB, int *elemC,
              int *mostC, int *temp1, int *temp2);
 
  static int compare(int arg, unsigned char networks[arg][4]);
 
  int compare_quads(const void *a, const void *b);
 
  void print_fun( int arg, unsigned char networks[arg][4], int *elemC, int *temp2, int *mostC,
                  int *elemB, int *temp1, int *mostB, int *elemA, int *mostA,
                  int *net_size_A, int *net_size_B, int *net_size_C);
 
 
 
  //read command line input and store the information
  int main(int argc, char** argv){
 
      //declar variable
      int arg = 0;
 
      //make argv into an int
      arg = atoi(argv[1]);
      //assign size to networks
       unsigned char networks[arg][4];
 
      //assign input to networks
      for (int j =0; j<1; ++j){
          if(argc == 1)
               {
                  printf("ERROR ERROR, you messed up\n");
              }
 
          else
          {
          // hold network addresses in a 2-d array, with 4 unsigned char
 
              for(int k = 0; k<arg; k++){
                  for (int i =0; i<4; i++){
 
                  scanf("%hhu.", &networks[k][i]);
                  //checks to see if scanf was working properly
                 // printf(" %hhu",networks[k][i]);
 
              }
                  //printf("\n");
              }}}
 
      int net_size_A = 0;
      int net_size_B = 0;
      int net_size_C = 0;
      int elemA = 0;
      int mostA = 0;
      int mostB = 0;
      int elemB = 0;
      int elemC = 0;
      int mostC = 0;
      int temp1 = 0;
      int temp2 = 0;
      int a = 0;
      int b =0;


      //other funtions that need to be ran
      compare(arg, networks);
      compare_quads(&a,&b);
 
       org_fun(arg, networks,
              &net_size_A, &net_size_B,
              &net_size_C, &elemA, &mostA,
              &mostB, &elemB, &elemC,
              &mostC, &temp1, &temp2);
 
      print_fun(arg, networks, &elemC, &temp2, &mostC,
                  &elemB, &temp1, &mostB, &elemA, &mostA,
                  &net_size_A, &net_size_B, &net_size_C);
 
              //test to see if values travel properly across functions
              //printf("%d++", net_size_A);
 
  return(0);
  }

comp_fun

 //declare libraries
   #include <string.h>
   #include <stdio.h>
   #include <stdlib.h>
  
   int compare_quads( const void *a, const void *b) {
        //stores memory for the sorted array
        return memcmp (a, b, 4);
  
  }
 
  //using qsort to sort the 2d array from least to greatest only depending on the network address
 
 
  static int compare(int arg, unsigned char networks[arg][4])
  {
      //sorts the network of size arg into the right slots
      qsort(networks, arg, sizeof(networks[0]), compare_quads);
 
          //checking to see if the order is correct
          //for (int k = 0; k< arg; k++){
          //    printf("%d.%d.%d.%d\n", networks[k][0],networks[k][1],networks[k][2],networks[k][3]);
          //    }
          //   printf("\n");
  return 0;
  }
 

org_fun

 //declare libraries
  #include <string.h>
  #include <stdio.h>
  #include <stdlib.h>
 
  //function is to sort each network function into a category, count how many are in each, count the most repeated and how many time
    s they are repeated
 void org_fun(int arg, unsigned char networks[arg][4],
              int *net_size_A,
              int *net_size_B,
              int *net_size_C,
              int *elemA,
              int *mostA,
              int *mostB,
              int *elemB,
              int *elemC,
              int *mostC,
              int *temp1,
              int *temp2){
 
 
 
  //my massive amount of declarations
      int tempA = 0;
      size_t countA;
      int tempB = 0;
      size_t countB;
      int tempC = 0;
      size_t countC;
      int temp2B = 0;
      int temp2C = 0;
      int temp3C = 0;
 
  //to make pointers function properly
 
 
 
 
      int anet_size_A = 0;
      int anet_size_B = 0;
      int anet_size_C = 0;
      int aelemA = 0;
      int amostA = 0;
      int amostB = 0;
      int aelemB = 0;
      int aelemC = 0;
      int amostC = 0;
      int atemp1 = 0;
      int atemp2 = 0;
 
 
      anet_size_A = *net_size_A;
      anet_size_B = *net_size_B;
      anet_size_C = *net_size_C;
      aelemA = *elemA;
      amostA = *mostA;
      amostB = *mostB;
      aelemB = *elemB;
      aelemC = *elemC;
      amostC = *mostC;
      atemp1 = *temp1;
      atemp2 = *temp2;
 
 
 
 
     //how many of each network is in each category( only depends on the first network number)
 
          // checks how many networks are in A
                    for (int k = 0; k < arg; k++){
              if      (networks[k][0]        <= 127){
                  if (networks[k][0] != networks[k+1][0]){
                      anet_size_A++;
                  }
 
              }
          }
 
          //checks how many networks are in B
          for (int k = 0; k < arg; k++){
              if (128 <= networks[k][0] && networks[k][0] <= 191){
                  if (networks[k][0] == networks[k+1][0]
                  &&  networks[k][1] == networks[k+1][1]){
                      }
                  else if(networks[k][0] != networks[k+1][0]){
                  anet_size_B++;
                  }
                  else{
                  anet_size_B++;
                  }
 
                 }
              }
          //checks how many networks in C
         for (int k = 0; k < arg; k++){
               if (192 <= networks[k][0] && networks[k][0] <= 223){
                     if    (networks[k][0] != networks[k+1][0]){
                          anet_size_C++;
                      }
                      else if (networks[k][0] == networks[k+1][0]
100                          &&  networks[k][1] != networks[k+1][1]){
                         anet_size_C++;
                     }
                     else if (networks[k][0] == networks[k+1][0]
                          &&  networks[k][1] == networks[k+1][1]
                          &&  networks[k][2] != networks[k+1][2]){
                         anet_size_C++;

                     }
             }
         }

             *net_size_A =anet_size_A;
             *net_size_B =anet_size_B;
             *net_size_C =anet_size_C;




 //this group of code is checking the size of and the most repeated networks.


         //checking to see which A network is most repeated and counting how many there are

                 for (int k = 0; k < arg; k++){
                     tempA = networks[k][0];
                     countA = 1;
                 for (int i = k+1; i<arg; i++){
                     if (networks[i][0] == tempA){
                         countA++;
                     }
                 }
                 if (amostA <= countA && networks[k][0] <= ){
                     amostA = countA;
                     aelemA = networks[k][0];

                 }
                 *mostA = amostA;
                   *elemA = aelemA;
                 }


         //checks to see if its working
         //printf("elem %d. most %d\n", elemA, mostA);



         //checking to see which B network is most repeated and counting how many there are
         for (int k = 0; k < arg; k++){
             tempB = networks[k][0];
             temp2B = networks[k][1];
             countB = 1;
             for (int i = k+1; i<arg; i++){
                 if (networks[i][0] == tempB && networks[i][1] == temp2B){
                     countB++;
                 }
             }
             if (amostB <= countB && networks[k][0] >= 128 && networks[k][0] <= 191){
                 amostB = countB;
                 aelemB = networks[k][0];
                 atemp1 = k;
             }
             *mostB = amostB;
             *elemB = aelemB;
             *temp1 = atemp1;





 }
         //printf("%d", networks[atemp1][0]);
         //checks to see if its working
         //printf("elem %d.%d, most %d\n", elemB, networks[temp1][1], mostB);


         //checking to see which C network is most repeated and counting how many there are
         for (int k = 0; k < arg; k++){
             tempC = networks[k][0];
             temp2C = networks[k][1];
             temp3C = networks[k][2];
             countC = 1;
             for (int i = k+1; i<arg; i++){
                 if (networks[i][0] == tempC && networks[i][1] == temp2C && networks[i][2] == temp3C){
                     countC++;
                 }
             }
             if (amostC <= countC && networks[k][0] >= 192 && networks[k][0] <= 223){
                 amostC = countC;
                 aelemC = networks[k][0];
                 atemp2 = k;
             }
             *mostC = amostC;
             *elemC = aelemC;
             *temp2 = atemp2;

        }
         //checks to see if function is working
         //printf("elem %d.%hhu.%hhu most %d\n", aelemC, networks[atemp2][1], networks[atemp2][2], amostC);

         //printf("%d\n", anet_size_A);
 }

                                                                                                               

print_fun

     //declare libraries
  #include <string.h>
  #include <stdio.h>
  #include <stdlib.h>
 
 
  void print_fun( int arg, unsigned char networks[arg][4], int *elemC, int *temp2, int *mostC,
                  int *elemB, int *temp1, int *mostB, int *elemA, int *mostA,
                  int *net_size_A, int *net_size_B, int *net_size_C){
              //checking to make sure my pointers work correctly
              //printf("please please please print");
              int anet_size_A = 0;
              int anet_size_B = 0;
              int anet_size_C = 0;
              int aelemA = 0;
              int amostA = 0;
              int amostB = 0;
              int aelemB = 0;
              int aelemC = 0;
              int amostC = 0;
              int atemp1 = 0;
              int atemp2 = 0;
 
              //uses pointers to access the elemnts inside the address
              anet_size_A = *net_size_A;
              anet_size_B = *net_size_B;
              anet_size_C = *net_size_C;
              aelemA = *elemA;
              amostA = *mostA;
              amostB = *mostB;
              aelemB = *elemB;
              aelemC = *elemC;
              amostC = *mostC;
              atemp1 = *temp1;
              atemp2 = *temp2;
 
         //printf("%d +++ %d\n", aelemB, networks[atemp1][1]);
          //if no code repeats for A
       if(amostA == 1){
 
              printf("Class A has %d networks\n", anet_size_A);
              printf("All a networks only have 1 host\n");
              printf("Class B has %d networks\n", anet_size_B);
              printf("Largest B network is %d.%d with %d hosts\n", aelemB, networks[atemp1][1], amostB);
              printf("Class C has %d networks\n", anet_size_C);
              printf("Largest C network is %d.%d.%d with %d hosts\n", aelemC, networks[atemp2][1], networks[atemp2][2], amostC);
 
      }
      //if no networks repeats for B
       if(amostB == 1){
 
              printf("Class A has %d networks\n", anet_size_A);
              printf("Largest A network is %d with %d hosts\n", aelemA, amostA);
              printf("Class B has %d networks\n", anet_size_B);
              printf("All B networks have only 1 host\n");
              printf("Class C has %d networks\n", anet_size_C);
              printf("Largest C network is %d.%d.%d with %d hosts\n", aelemC, networks[atemp2][1], networks[atemp2][2], amostC);
 
      }
      //if no networks repeats for C
     if (amostC == 1){
 
              printf("Class A has %d networks\n", anet_size_A);
              printf("Largest A network is %d with %d hosts\n", aelemA, amostA);
              printf("Class B has %d networks\n", anet_size_B);
              printf("Largest B network is %d.%d with %d hosts\n", aelemB, networks[atemp1][1], amostB);
              printf("Class C has %d networks\n", anet_size_C);
              printf("All C networks have only 1 host\n");
                                                              
   }
 
 
     //for any other situtation
      else{
 
              printf("Class A has %d networks\n", anet_size_A);
              printf("Largest A network is %d with %d hosts\n", aelemA, amostA);
              printf("Class B has %d networks\n", anet_size_B);
              printf("Largest B network is %d.%d with %d hosts\n", aelemB, networks[atemp1][1], amostB);
              printf("Class C has %d networks\n", anet_size_C);
              printf("Largest C network is %d.%d.%d with %d hosts\n", aelemC, networks[atemp2][1], networks[atemp2][2], amostC);
 
      }
 
 
  }
 
                            

When I run make I receive this

[p18d541@csci112 program1]$ make
gcc -c main.c -Wall
main.c:13:12: warning: ‘compare’ used but never defined
   13 | static int compare(int arg, unsigned char networks[arg][4]);
      |            ^~~~~~~
gcc -c org_fun.c -Wall
gcc -c comp_fun.c -Wall
comp_fun.c:15:12: warning: ‘compare’ defined but not used [-Wunused-function]
   15 | static int compare(int arg, unsigned char networks[arg][4])
      |            ^~~~~~~
gcc -c print_fun.c -Wall
gcc main.o org_fun.o comp_fun.o print_fun.o -Wall -o program1
/usr/bin/ld: main.o: in function `main':
main.c:(.text+0x185): undefined reference to `compare'
collect2: error: ld returned 1 exit status
make: *** [makefile:3: program1] Error 1

Before, I had all of these codes in one file, but I needed to split them for a requirement. But the code was working properly before. So I am wondering if something went wrong with my refactoring.

When you declare something at the top level of a translation unit with the static keyword, you are saying that it's name can only be used in that translation unit. ("File" isn't really the right word, but if you find "translation unit" confusing, start by thinking of them as files. But you need to remember that it also contains the program text incorporated with #include directives.)

Static names are not recorded in the object file (except possibly in optional debugging information) and so no other object file in the project can see or use the name for that object. (Which means that they are free to use the same name for other objects.)

That doesn't mean that it's not possible to share the actual object or function, since you are free to pass pointers around between translation units. But you cannot use the name in another translation unit.

This is useful for functions which are internal to a library. Since C does not have namespaces, you really don't want to make all the names in a program universally visible; that's a recipe for disaster because it would inevitably lead to the same name being applied to two completely different things.

But if you want to call a function which is defined in a different translation unit, you need to avoid declaring the function as static .

That's what has happened here. You define a static function in one translation unit and attempt to use it in a different one; the two names are the same but because they are static, they don't refer to the same thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM