理解C链接器错误:多重定义
Understanding C linker error: multiple definition
我有一个包含多个头文件和.cpp
文件的项目。所有头文件都包含保护。
有一个名为Constants.h
的文件,我在其中定义了一些常量。其中一些带有定义,一些是常量变量。
还有更多的头.cpp
文件对,其中包含代码。其中一个确实包含类,其他的则不包含。
当我把我的文件包括到我的主文件(arduino草图)中时,我会得到很多链接器错误,声称有些变量有多个定义。
我读到,这主要发生在包含.c
或.cpp
文件时,而我没有这样做。所有.cpp
文件都只包含相应的头文件。
我确实设法找到了多个解决方案建议:
1)inline
:
通过函数,inline
可以用来解决这个问题。然而,对于变量来说,这是不可能的。
2)匿名namespace
:
这是我使用的解决方案之一。我在所有有问题的定义周围放置了匿名名称空间。它确实起了作用,但我不明白为什么会起作用。有人能帮我理解吗?
3)将定义移动到.cpp
文件中:
这是我有时使用的另一种方法,但这并不总是可能的,因为我需要在其他代码中使用我的一些定义,这些定义不属于这个头文件或它的代码(我承认这是糟糕的设计)。
有人能向我解释一下问题到底在哪里,以及为什么这些方法有效吗?
其中一些带有定义,一些作为常量变量。
在C中,const
并不意味着与在C++中相同的东西。如果你有这个:
const int foo = 3;
在标头中,任何包含标头的C++转换单元都将有一个名为foo
的静态变量(命名空间范围中的const
表示内部链接)。此外,foo
甚至可以被许多C++构造认为是一个常数表达式。
C中的情况并非如此。foo
是具有外部链接的文件范围内的对象。因此,您将有来自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
中,将声明所有变量(即为它们分配空间),在包括glo.h
的所有其他c文件中,所有变量都是已知的。
不应该在头文件中声明任何对象,应该将其移动到c\c++文件中。
在标题中,您可以:
- 声明类型,如:
class
es、struct
s、typedef
s等 - 提出函数(而不是类)的声明
- 放入内联(或类中)函数(+body)
- 您可以添加
extern
声明 - 你可以把你的宏
static
声明可能会多次声明内容,因此不建议这样做。
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件