未定义对"_ *"链接器错误的引用 [英] Undefined reference to '_*' linker error
问题描述
我在编译/链接以下C代码时遇到麻烦.链接器将引发类似于以下的错误:
pso.o:pso.c:(.text+0x41): undefined reference to '_ps'
...
pso.o:pso.c:(.text+0x93): more undefined references to '_ps' follow
这是我第一次为gcc编写C代码,所以我不确定如何解决此问题.我假设因为struct PS是我的头文件定义的,所以它不以某种方式未链接到pso.c.但是,我确实在该源文件的顶部使用了#include"ps.h"语句.
我在下面包括了相关的源文件和头文件,以及我正在使用的make文件.编写可链接的C代码是否缺少我的基本概念?
谢谢!哦,这是一个粒子群优化器,如果您想知道的话:)
main.c文件:
#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);
}
有问题的文件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); */
}
定义数据结构PS(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
最后,我正在使用的make文件:
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)
在"ps.h"中,有一行
extern PS ps;
-但这仅是声明 ps
(即断言它存在于某处);它没有提供定义(即在此处将其存在).您应该做的是,第一步,替换
#ifndef MAIN
extern PS ps;
#endif
只需
extern PS ps;
然后第二步进入pso.c
并在该文件的顶层添加
PS ps = {};
(或PS ps;
或extern PS ps = {};
).如果您的C编译器很旧或很笨,足以抱怨空括号,请改写PS ps = {0};
;否则,请使用PS ps = {0};
. {}
是一种C ++'03主义,我相信它会被C'11所采用,但我对此不确定100%.
简而言之,关于声明的规则是:如果为初始化器提供 I have included the relevant source files and header file below, as well as the make file I am using. Is there a fundamental concept I am missing for writing linkable C code? Thank you! Oh, and it's a particle swarm optimizer, if you were wondering :) The main.c file: The file in question, pso.c: The header file which defines the data structure PS (ps.h): Lastly, the make file I am using:
In "ps.h", you have the line — but this only declares with just and then, step two, go into (or Briefly, the rule about declarations is: If you provide an initializer with 这篇关于未定义对"_ *"链接器错误的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!=
,则声明必须是一个定义(因为在这里还可以如何初始化变量?).否则,如果您使用extern
存储类,则它不是 定义(因为助记符,您是说该变量在该文件中 extern 存在) .否则,它是一个定义(但在K& RC中,它是一个
#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);
}
#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); */
}
#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
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)
extern PS ps;
ps
(i.e. assert it exists somewhere); it doesn't provide a definition (i.e. make it exist here). What you should do is, step one, replace#ifndef MAIN
extern PS ps;
#endif
extern PS ps;
pso.c
and somewhere at the top level of that file addPS ps = {};
PS ps;
, or extern PS ps = {};
). If your C compiler is old or dumb enough to complain about the empty braces, write PS ps = {0};
instead; {}
is a C++'03-ism that I believe is being adopted into C'11 but I'm not 100% certain about that.=
, then the declaration must be a definition (because how else could you initialize the variable here?). Otherwise, if you used the extern
storage-class, it's not a definition (because mnemonically, you're saying that the variable exists extern-ally to this file). Otherwise, it's a definition (but in K&R C it's a tentative definition, and many compilers will either put it in the BSS section by default or else provide a command-line option to do so).