C 错误:未定义对函数的引用,但它已定义 [英] C error: undefined reference to function, but it IS defined

查看:35
本文介绍了C 错误:未定义对函数的引用,但它已定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是一个简单的程序,但我不断收到此编译器错误.我使用 MinGW 作为编译器.

这是头文件,point.h:

//输入笛卡尔点类型定义结构{双x;双y;} 观点;点创建(双x,双y);点中点(点p,点q);

这里是 point.c:

//这是点类型的实现#include "point.h"int main() {返回0;}点创建(双x,双y){点 p;p.x = x;p.y = y;返回 p;}点中点(点p,点q){中点;mid.x = (p.x + q.x)/2;mid.y = (p.y + q.y)/2;返回中段;}

这就是编译器问题的来源.我不断收到:

<块引用>

testpoint.c: 对'create(double x, double y)'的未定义引用

虽然它是在 point.c. 中定义的

这是一个名为 testpoint.c 的单独文件:

#include "point.h"#include #include int main() {双 x = 1;双 y = 1;点 p = create(x, y);断言(p.x == 1);返回0;}

我不知道可能是什么问题.

解决方案

你是如何进行编译和链接的?您需要指定两个文件,例如:

gcc testpoint.c point.c

...以便它知道将两者的功能链接在一起.但是,使用现在编写的代码,您将遇到相反的问题:main 的多个定义.您将需要/想要消除一个(无疑是 point.c 中的那个).

在较大的程序中,您通常会分别编译和链接,以避免重新编译任何未更改的内容.您通常通过 makefile 指定需要完成的工作,并使用 make 来完成这项工作.在这种情况下,你会有这样的事情:

OBJS=testpoint.o point.otestpoint.exe: $(OBJS)gcc $(OJBS)

第一个只是目标文件名称的宏.您可以使用 $(OBJS) 对其进行扩展.第二个规则是告诉 make 1) 可执行文件依赖于目标文件,以及 2) 告诉它如何在/如果与目标文件相比过期时创建可执行文件.

大多数版本的 make(包括 MinGW 中的那个,我很确定)都有一个内置的隐式规则"来告诉他们如何从 C 源文件创建目标文件.它通常看起来大致如下:

.c.o:$(CC) -c $(CFLAGS) $<

这假设 C 编译器的名称在名为 CC 的宏中(隐式定义如 CC=gcc)并允许您在名为 CFLAGS 的宏中指定您关心的任何标志(例如,CFLAGS=-O3 打开优化)和 $< 是一个特殊的宏,它扩展到源文件的名称.>

您通常将其存储在名为 Makefile 的文件中,并且要构建您的程序,您只需在命令行中键入 make.它隐式地寻找一个名为 Makefile 的文件,并运行它包含的任何规则.

这样做的好处是 make 会自动查看文件上的时间戳,因此它只会重新编译自上次编译后发生更改的文件(即文件其中.c"文件的时间戳比匹配的.o"文件更新.

另请注意,1) 在大型项目中,make 的使用方法有很多变化,2) 还有很多替代方法可供选择.我只触及了最低限度的高点.

Just a simple program, but I keep getting this compiler error. I'm using MinGW for the compiler.

Here's the header file, point.h:

//type for a Cartesian point
typedef struct {
  double x;
  double y;
} Point;

Point create(double x, double y);
Point midpoint(Point p, Point q);

And here's point.c:

//This is the implementation of the point type
#include "point.h"

int main() {
  return 0;
}
Point create(double x, double y) {
  Point p;
  p.x = x;
  p.y = y;
  return p;
}

Point midpoint(Point p, Point q) {
  Point mid;
  mid.x = (p.x + q.x) / 2;
  mid.y = (p.y + q.y) / 2;
  return mid;
}

And here's where the compiler issue comes in. I keep getting:

testpoint.c: undefined reference to 'create(double x, double y)'

While it is defined in point.c.

This is a separate file called testpoint.c:

#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
  double x = 1;
  double y = 1;
  Point p = create(x, y);

  assert(p.x == 1);
  return 0;
}

I'm at a loss as to what the issue could be.

解决方案

How are you doing the compiling and linking? You'll need to specify both files, something like:

gcc testpoint.c point.c

...so that it knows to link the functions from both together. With the code as it's written right now, however, you'll then run into the opposite problem: multiple definitions of main. You'll need/want to eliminate one (undoubtedly the one in point.c).

In a larger program, you typically compile and link separately to avoid re-compiling anything that hasn't changed. You normally specify what needs to be done via a makefile, and use make to do the work. In this case you'd have something like this:

OBJS=testpoint.o point.o

testpoint.exe: $(OBJS)
    gcc $(OJBS)

The first is just a macro for the names of the object files. You get it expanded with $(OBJS). The second is a rule to tell make 1) that the executable depends on the object files, and 2) telling it how to create the executable when/if it's out of date compared to an object file.

Most versions of make (including the one in MinGW I'm pretty sure) have a built-in "implicit rule" to tell them how to create an object file from a C source file. It normally looks roughly like this:

.c.o:
    $(CC) -c $(CFLAGS) $<

This assumes the name of the C compiler is in a macro named CC (implicitly defined like CC=gcc) and allows you to specify any flags you care about in a macro named CFLAGS (e.g., CFLAGS=-O3 to turn on optimization) and $< is a special macro that expands to the name of the source file.

You typically store this in a file named Makefile, and to build your program, you just type make at the command line. It implicitly looks for a file named Makefile, and runs whatever rules it contains.

The good point of this is that make automatically looks at the timestamps on the files, so it will only re-compile the files that have changed since the last time you compiled them (i.e., files where the ".c" file has a more recent time-stamp than the matching ".o" file).

Also note that 1) there are lots of variations in how to use make when it comes to large projects, and 2) there are also lots of alternatives to make. I've only hit on the bare minimum of high points here.

这篇关于C 错误:未定义对函数的引用,但它已定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆