了解C链接器错误:多个定义

时间:2019-02-04 14:19:09

标签: c++ arduino include

我有一个包含多个头文件和.cpp文件的项目。 所有头文件都包含防护。

有一个名为Constants.h的文件,其中定义了一些常量。其中一些带有定义,一些作为常量。

有更多的标头-.cpp-文件对,其中包含代码。其中一个确实包含一个类,而其他则没有。

当我将文件包含到主文件(一个arduino草图)中时,我收到很多链接器错误,声称某些变量有多个定义。

我了解到,这主要是在您包含.c.cpp文件时发生的,而我没有这样做。所有.cpp文件仅包含其相应的头文件。

我确实找到了多个解决方案建议:

1)inline

通过功能,inline可用于解决此问题。但是,使用变量是不可能的。

2)匿名namespace

这是我使用的解决方案之一。我将匿名名称空间放在我遇到的所有有问题的定义周围。它确实起作用,但是我不明白为什么起作用。有人可以帮我理解吗?

3)将定义移至.cpp文件中:

这是我有时使用的另一种方法,但这并不总是可行的,因为我需要其他代码中的一些定义,而不是这个头文件或其代码(我承认这是错误的设计)。

谁能向我解释问题出在哪里以及这些方法为何起作用?

3 个答案:

答案 0 :(得分:3)

  

其中一些带有定义,一些是常量。

在C const中并不表示与C ++中相同。如果您有这样的话:

const int foo = 3;

在标头中,那么任何包含标头的C ++转换单元都将具有名为foo static 变量(名称空间范围内的const表示内部链接)。而且,foo甚至可以被许多C ++构造视为常量表达式。

在C中不是这种情况。foo是文件范围内具有外部链接的对象。因此,您将从C翻译单元获得多个定义。

一个快速的解决方法是将定义更改为类似这样的内容:

static const int foo = 3;

这在C ++中是多余的,但在C中是必需的。

答案 1 :(得分:2)

除了Story Teller的出色解释之外,要定义全局变量,请使用以下内容:

// module.h
#include "glo.h"

// glo.h
#ifndef EXTERN
# define EXTERN extern
#endif
EXTERN int myvar;

// main.c
#define EXTERN
#include "glo.h"

main.c中将声明所有变量(即为它们分配空间),在所有其他包含glo.h的c文件中,所有变量都将是已知的。

答案 2 :(得分:0)

您不应在头文件中声明任何对象,而应将其移动到c \ c ++文件中。

在标题中,您可以:

  • 声明类型,例如:classstructtypedef等。
  • 提交(不是类)函数的声明
  • 放入内联(或在类中)函数(+正文)
  • 您可以添加extern声明。
  • 您可以放置​​宏。

static声明可以声明多次,因此不建议这样做。