ups*_*sdn 55 c function linker-errors undefined-reference
只是一个简单的程序,但我一直得到这个编译错误.我正在使用MinGW作为编译器.
这是头文件,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);
Run Code Online (Sandbox Code Playgroud)
这是重点.:
//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;
}
Run Code Online (Sandbox Code Playgroud)
这就是编译器问题的来源.我不断得到:
testpoint.c:对'create(double x,double y)'的未定义引用
虽然它在point.c中定义.
这是一个名为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;
}
Run Code Online (Sandbox Code Playgroud)
我不知道问题是什么.
Jer*_*fin 84
你是如何进行编译和链接的?您需要指定两个文件,例如:
gcc testpoint.c point.c
Run Code Online (Sandbox Code Playgroud)
...因此它知道将两者的功能链接在一起.然而,使用现在编写的代码,您将遇到相反的问题:多个定义main.你需要/想要消除一个(毫无疑问是点c中的那个).
编辑:在较大的程序中,您通常单独编译和链接,以避免重新编译任何未更改的内容.您通常通过makefile指定需要完成的操作,并用于make完成工作.在这种情况下你会有这样的事情:
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
Run Code Online (Sandbox Code Playgroud)
第一个只是目标文件名称的宏.你得到了扩展$(OBJS).第二个是告诉make 1)可执行文件依赖于目标文件,以及2)告诉它如何在/如果它与目标文件相比过时而创建可执行文件的规则.
make的大多数版本(包括MinGW中的那个我很确定)都有一个内置的"隐式规则"来告诉他们如何从C源文件创建目标文件.它通常看起来大致如下:
.c.o:
$(CC) -c $(CFLAGS) $<
Run Code Online (Sandbox Code Playgroud)
这假设C编译器的名称位于名为CC的宏中(隐式定义为CC=gcc),并允许您在命名的宏中指定您关心的任何标志CFLAGS(例如,CFLAGS=-O3打开优化),并且$<是一个特殊的宏,它扩展为源文件的名称.
您通常将其存储在一个名为的文件中Makefile,并且要构建您的程序,只需make在命令行键入即可.它隐式查找名为的文件Makefile,并运行它包含的任何规则.
这样做的好处是make自动查看文件上的时间戳,因此它只会重新编译自上次编译文件以来已更改的文件(即".c"文件最近的文件时间戳比匹配的".o"文件).
另请注意1)在涉及大型项目时,如何使用make有很多变化,2)还有很多替代品可供选择.我这里只打出了最低点.
cp.*_*ngr 10
我最近遇到过这个问题.在我的例子中,我的IDE设置为根据其扩展选择在每个文件上使用哪个编译器(C或C++),并且我试图.c从C++代码调用C函数(即从文件中).
.hC函数的文件没有包含在这种防范中:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
我可以添加,但我不想修改它,所以我只是把它包含在我的C++文件中,如下所示:
extern "C" {
#include "legacy_C_header.h"
}
Run Code Online (Sandbox Code Playgroud)
(帽子向UncaAlby提示,因为他清楚地解释了外部"C"的影响.)
我认为问题在于,当你尝试编译testpoint.c时,它包含了point.h,但它不了解point.c.由于point.c具有定义create,因此没有point.c将导致编译失败.
我不熟悉MinGW,但你需要告诉编译器寻找point.c.例如,使用gcc,您可以这样做:
gcc point.c testpoint.c
Run Code Online (Sandbox Code Playgroud)
当然,正如其他人指出的那样,您还需要删除一个main功能,因为您只能拥有一个功能.