Understanding C linker error: multiple definition
Understanding C linker error: multiple definition
我有一个包含多个 header 个文件和 .cpp
个文件的项目。
所有 header 文件都包含守卫。
有一个名为 Constants.h
的文件,我在其中定义了一些常量。其中一些带有定义,一些作为常量变量。
有更多 header-.cpp
-文件对,其中包含代码。其中一个确实包含 class,其他的则没有。
当我将我的文件包含到我的主文件(arduino sketch)中时,我收到很多链接器错误,声称某些变量有多个定义。
我了解到这主要发生在您包含 .c
或 .cpp
文件时,而我不这样做。所有 .cpp
个文件仅包含相应的 header 个文件。
我确实找到了多个解决方案:
1) inline
:
有了函数,inline
就可以解决这个问题了。但是,这对于变量是不可能的。
2) 匿名 namespace
:
这是我使用的解决方案之一。我在所有有问题的定义周围放置了匿名名称空间。它确实有效,但我不明白为什么会这样。谁能帮我理解一下?
3) 将定义移动到 .cpp
个文件中:
这是我有时使用的另一种方法,但并不总是可行,因为我需要在其他代码中定义一些不属于此 header 文件或其代码(我承认是糟糕的设计)。
任何人都可以向我解释问题到底出在哪里以及为什么这些方法有效吗?
Some of these with defines, some as constant variables.
在 C 中 const
与在 C++ 中的含义不同。如果你有这个:
const int foo = 3;
在 header 中,那么任何包含 header 的 C++ 翻译单元都会有一个名为 foo
的 static 变量(const
在命名空间范围内意味着内部链接)。此外,foo
甚至可以被许多 C++ 结构视为常量表达式。
在 C 中情况并非如此。foo
在文件范围内有一个 object,具有外部链接。所以你会有多个来自 C 翻译单元的定义。
快速解决方法是将定义更改为如下内容:
static const int foo = 3;
这在 C++ 中是多余的,但在 C 中是必需的。
除了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
中,所有变量都将被声明(即为它们分配space),在包含glo.h
的所有其他c文件中,所有变量都是已知的。
你不应该在头文件中声明任何对象,这应该被移动到 c\c++ 文件。
在页眉中您可以:
- 声明类型,例如:
class
es、struct
s、typedef
s 等
- 提出(不是类)函数的声明
- 放入内联(或 类)函数(+正文)
- 您可以添加
extern
声明。
- 你可以放你的宏。
一个static
声明可能会声明多次,所以不推荐。
我有一个包含多个 header 个文件和 .cpp
个文件的项目。
所有 header 文件都包含守卫。
有一个名为 Constants.h
的文件,我在其中定义了一些常量。其中一些带有定义,一些作为常量变量。
有更多 header-.cpp
-文件对,其中包含代码。其中一个确实包含 class,其他的则没有。
当我将我的文件包含到我的主文件(arduino sketch)中时,我收到很多链接器错误,声称某些变量有多个定义。
我了解到这主要发生在您包含 .c
或 .cpp
文件时,而我不这样做。所有 .cpp
个文件仅包含相应的 header 个文件。
我确实找到了多个解决方案:
1) inline
:
有了函数,inline
就可以解决这个问题了。但是,这对于变量是不可能的。
2) 匿名 namespace
:
这是我使用的解决方案之一。我在所有有问题的定义周围放置了匿名名称空间。它确实有效,但我不明白为什么会这样。谁能帮我理解一下?
3) 将定义移动到 .cpp
个文件中:
这是我有时使用的另一种方法,但并不总是可行,因为我需要在其他代码中定义一些不属于此 header 文件或其代码(我承认是糟糕的设计)。
任何人都可以向我解释问题到底出在哪里以及为什么这些方法有效吗?
Some of these with defines, some as constant variables.
在 C 中 const
与在 C++ 中的含义不同。如果你有这个:
const int foo = 3;
在 header 中,那么任何包含 header 的 C++ 翻译单元都会有一个名为 foo
的 static 变量(const
在命名空间范围内意味着内部链接)。此外,foo
甚至可以被许多 C++ 结构视为常量表达式。
在 C 中情况并非如此。foo
在文件范围内有一个 object,具有外部链接。所以你会有多个来自 C 翻译单元的定义。
快速解决方法是将定义更改为如下内容:
static const int foo = 3;
这在 C++ 中是多余的,但在 C 中是必需的。
除了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
中,所有变量都将被声明(即为它们分配space),在包含glo.h
的所有其他c文件中,所有变量都是已知的。
你不应该在头文件中声明任何对象,这应该被移动到 c\c++ 文件。
在页眉中您可以:
- 声明类型,例如:
class
es、struct
s、typedef
s 等 - 提出(不是类)函数的声明
- 放入内联(或 类)函数(+正文)
- 您可以添加
extern
声明。 - 你可以放你的宏。
一个static
声明可能会声明多次,所以不推荐。