Undefined link to error _ _ '' linker

I had a problem compiling / linking the following C code. The compiler throws errors that look like this:

pso.o:pso.c:(.text+0x41): undefined reference to '_ps' ... pso.o:pso.c:(.text+0x93): more undefined references to '_ps' follow 

This is my first time writing C code for gcc, so I don’t know how to fix this problem. I assume that since struct PS is defined by my header file, it is somehow not related to pso.c. However, I used the #include "ps.h" instruction at the top of this source file.

I have included the appropriate source files and header file below, as well as the make file that I use. Is there a basic concept that I'm missing for writing C middleware?

Thanks! Oh, and it's a particle swarm optimizer if you're interested :)

Main.c file:

 #define MAIN #include<stdio.h> #include<stdlib.h> #include<time.h> #include "ps.h" int main(int argc, char *argv[]) { int c; double test; int test_int; srand(time(NULL)); printf("starting pso\n"); pso(); printf("finished pso\n"); return(0); } 

This file, pso.c:

 #include<stdio.h> #include "ps.h" double it(double C[]); void pso() { int i; int j; int k; puts("Now in PSO"); /* Initialize PSO controls */ psoi(); /* Initialize particle positions and velocities */ for (i=0;i<MPART;i++){ for(j=1;j<MINDV;j++){ /* positions */ ps.X[i][j]=(-1+2*random())*ps.bup; /* velocities */ ps.V[i][j] = (-1+2*random())*ps.bup / ps.vred; /* Transform */ ps.ut[j] = (ps.X[i][j] - ps.blo)/(ps.bup - ps.blo) * (ps.bnd_hi[i] - ps.bnd_lo[i]) + ps.bnd_lo[i]; } /* Evaluate Finess */ ps.fitness = fit(ps.ut); /* Update particle best position */ ps.pbest[i]=ps.fitness; /* Update swarm best position */ if(ps.pbest[i] < ps.sbest){ for(j=0;j<MINDV;j++){ ps.g[j]=ps.p[i][j]; } ps.sbest = ps.pbest[i]; } } /* Convergenve Loop */ for(k=2;k<ps.maxk;k++){ for(i=1;i<MPART;i++){ for(j=1;j<MINDV;j++){ /* Velocity Update */ ps.rp = random(); ps.rg = random(); ps.rr = random(); ps.chi = 0.7298; ps.V[i][j] = ps.chi * ( ps.V[i][j] + ps.phi_p*ps.rp*(ps.p[i][j] - ps.X[i][j]) + ps.phi_g*ps.rg*(ps.g[j] - ps.X[i][j])); /* Position Update */ ps.X[i][j] = ps.X[i][j] + ps.V[i][j]; /* Transform */ ps.ut[j] = (ps.X[i][j]-ps.blo)/(ps.bup-ps.blo)*(ps.bnd_hi[i]-ps.bnd_lo[i])+ps.bnd_lo[i]; } /* Evaluate Fitness */ ps.fitness = fit(ps.ut); /* Update particle best position */ if(ps.fitness < ps.pbest[i]){ for(j=0;j<MINDV;j++){ ps.p[i][j]=ps.X[i][j]; } ps.pbest[i]=ps.fitness; } /* Update swarm best position */ if(ps.pbest[i] < ps.sbest){ for(j=0;j<MINDV;j++){ ps.g[j]=ps.p[i][j]; } ps.sbest = ps.pbest[i]; printf("%f \n",ps.sbest); } } /* Convergence Criteria */ } /* return(0); */ } 

The header file that defines the PS data structure (ps.h):

 #ifndef _PS_ #define _PS_ #define MPART 30 #define MINDV 2 typedef struct{ /* Design Space */ double X[MPART][MINDV]; double V[MPART][MINDV]; double p[MPART][MINDV]; double u[MINDV]; double ut[MINDV]; double sbest; double sbest_old; double g[MINDV]; double gt[MINDV]; double pbest[MPART]; double pbest_sort[MPART]; double blo; double bup; double fitness; double maxk; double bnd_lo[MINDV]; double bnd_hi[MINDV]; /* PSO behavior */ int psotype; double w; double phi_p; double phi_g; double gam; double chi; double vred; double rp; double rg; double rr; }PS; /* Dependent Source File Functions */ extern void pso(); extern double fit(double C[2]); #ifndef MAIN extern PS ps; #endif #endif 

Finally, the make file that I use:

 CC=gcc CFLAGS= -I. DEPS = ps.h OBJ = main.o pso.o psoi.o fit.o default: program %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) program: $(OBJ) gcc -o $@ $^ $(CFLAGS) 
0
source share
3 answers

In "ps.h" you have a line

 extern PS ps; 

- but it only declares ps (i.e. claims to exist somewhere); he does not give a definition (i.e. does it here). What you need to do, step one, replace

 #ifndef MAIN extern PS ps; #endif 

with just

 extern PS ps; 

and then, step two, go to pso.c and somewhere at the top level of this file add

 PS ps = {}; 

(or PS ps; or extern PS ps = {}; ). If your C compiler is outdated or not dumb enough to complain about empty curly braces, write PS ps = {0}; ; {} is C ++ '03 -ism, which I believe is accepted in C'11, but I'm not 100% sure.

In short, the rule about declarations: if you provided an initializer with = , the declaration should be a definition (because how else could you initialize a variable here?). Otherwise, if you used the storage class extern , this is not a definition (since it is mnemonic, you say that the variable exists extern-ally for this file). Otherwise, it is a definition (but in K & RC it is a preliminary definition , and many compilers either put it in the default BSS section, or specify a command line parameter for this).

+2
source

You declare ps as extern , but you never define it anywhere. To write

 PS ps; 

in one of the C. files

+3
source

The linker output is a bit confusing, it really complains that the definition of the ps object is missing. You declared it extern , but you have not defined it anywhere.

+2
source

All Articles