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.