无法整理出多个定义
Posted
技术标签:
【中文标题】无法整理出多个定义【英文标题】:Can't sort out multiple definition 【发布时间】:2017-08-27 20:55:11 【问题描述】:我有三个头文件ball.h
、wrappers.h
、graphics.h
和对应的.c
-文件。每个.c
文件都包含其对应的头文件,所有这些头文件都有包含保护。此外,wrappers.c
包括graphics.h
和wrappers.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.o
和ball.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
时,都会得到定义的 circleRadius
和 circleColor
常量的全局副本。要么它们需要是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
时,都会获得已定义的 circleRadius
和 circleColor
常量的全局副本。要么他们需要是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 控件无法显示,原因可能是下列其中之一