无法整理多重定义

Can't sort out multiple definition

我有三个头文件 ball.hwrappers.hgraphics.h 以及对应的 .c 文件。每个 .c 文件都包含其相应的头文件,所有头文件都有包含保护。此外,wrappers.c 包括 graphics.hwrappers.h 包括 ball.h,它定义了一对 const float(以及更多)。

在一个 makefile 中,我为上面的每一对都有一个表单条目 name.o: name.c name.h$(CC) -c $^。最后,我有一个包含上述每个头文件的 test.c 文件(具有主要功能),其 makefile 条目是 test: test.c wrappers.o graphics.o ball.o$(CC) $^ -o $@.

编译test导致多重定义错误,说前面提到的两个const float首先定义在wrappers.oball.o.

我想这是因为 wrappers.h 包含 ball.h,但我不知道如何解决这个问题,除非移动有问题的变量,或者更糟的是,更改我的代码。问题是由于笨拙的包含,还是由于 makefile 的结构?

ball.h 摘录:

#ifndef BALL_H
#define BALL_H

const float circleRadius = 0.025;
const float circleColor = 0;

typedef struct {
    float x,y; // etc
} ball_t;

// various function prototypes

#endif /* BALL_H */

正在将评论转化为答案。

在 C 中,每次包含 ball.h 时,您都会获得定义的 circleRadiuscircleColor 常量的全局副本。它们需要是 static(以及 const float),或者您需要在 header 中声明它们 extern(没有初始化程序)并将它们完全定义为一个源文件。

这是 C++ 中的规则与 C 中的规则不同的区域;请注意您使用的编译器。

I haven't used extern before; how should I use it here? (And now that you mention it, static would probably be a good idea for this particular project, but I'd like to try the extern solution as well.)

在header中写入:

extern const float circleRadius;

在一个源文件中,写入:

const float circleRadius = 0.025;

也重复颜色。对于整数值,您可以考虑使用 enum 代替(有关更多详细信息,请参阅 static const vs #define vs enum。)对于浮点数(或者实际上是整数值),您可以在 header 中使用它:

#define CIRCLE_RADIUS 0.025

显然,您需要更改引用的拼写(对于 #define — 以及许多 enum — 常量,全部大写是习惯做法)。

另外,正如 WhozCraig in a comment, the question Why do we need the extern keyword in C if file scope declarations have external linkage by default? 所指出的,可能会有帮助。