无法整理出多个定义

Posted

技术标签:

【中文标题】无法整理出多个定义【英文标题】:Can't sort out multiple definition 【发布时间】:2017-08-27 20:55:11 【问题描述】:

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

在生成文件中,我对上述每一对都有一个表单条目 name.o: name.c name.h$(CC) -c $^。最后,我有一个 test.c 文件(带有一个 main 函数),其中包含上述每个头文件,它的 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 */

【问题讨论】:

"...包括 ball.h,它定义了一对 const float (以及更多)。" - 这个问题应该包括该代码。无代码,我们诉诸占卜。我的水晶球告诉我你是在标题中直接定义这些变量,而不是在标题中声明它们extern,并实际上在单个 C 翻译单元中定义它们。或者,您可以通过在标题中声明+定义它们static 来处理多个定义。对于常量,任何一种方法都应该有效。 在 C 中,每次包含 ball.h 时,都会得到定义的 circleRadiuscircleColor 常量的全局副本。要么它们需要是static(以及const float),要么你需要在标题中声明它们extern 并在一个源文件中完全定义它们。这是 C++ 中的规则与 C 中的规则不同的领域;注意你使用的编译器。 谢谢大家。我之前没用过extern,这里应该怎么用呢? (既然你提到了它,static 可能是这个特定项目的好主意,但我也想尝试extern 解决方案。) extern const float circleRadius; 在标题中。在一个源文件中:const float circleRadius = 0.025;。也重复颜色。对于整数值,您可以考虑改用enum。对于浮点数,您可以在标题中使用#define CIRCLE_RADIUS 0.025 This question 可能很有用。 【参考方案1】:

将 cmets 转换为答案。

在 C 中,每次包含 ball.h 时,都会获得已定义的 circleRadiuscircleColor 常量的全局副本。要么他们需要是static(以及const float),要么你需要在标题中声明他们extern(没有初始化器)并在一个源文件中完全定义它们。

这是 C++ 中的规则与 C 中的规则不同的地方;注意你使用的编译器。

我之前没用过extern;我应该如何在这里使用它? (既然你提到它,static 可能是这个特定项目的好主意,但我也想尝试extern 解决方案。)

在标题中写:

extern const float circleRadius;

在一个源文件中,写:

const float circleRadius = 0.025;

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

#define CIRCLE_RADIUS 0.025

显然,您会更改引用的拼写(所有大写字母都是习惯的 #define — 以及许多 enum — 常量)。

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

【讨论】:

以上是关于无法整理出多个定义的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MapControl 中动态使用具有多个引脚的多个自定义弹出窗口

一个或多个ActiveX 控件无法显示,原因可能是下列其中之一

自定义水平弹出过渡无法正常工作

同一视图上的多个手势(从可滚动视图中拖出视图)无法正常工作?

无法配置问题出在哪里:未定义“urllib”

如果我进行自定义查询,我无法在 phpmyadmin 中导出