函数的多个定义,即使在包含保护中定义
Multiple definitions of a function even though defined inside an include guard
假设我有一个头文件myheader.h
定义如下:
#ifndef MY_HEADER
#define MY_HEADER
int MyFunction(int x)
{
return x + 1;
}
#endif
然后,我有两个源文件,它们都#include
这个头文件。这给了我一个编译错误:
multiple definitions of 'MyFunction(int)'
为什么我的头文件中的包含保护不会阻止它被定义两次?
您需要
将函数标记为inline
,如下所示:
#ifndef MY_HEADER
#define MY_HEADER
inline int MyFunction(int x)
{
return x + 1;
}
#endif
解释:
每次在任何.cpp文件中包含 .h 时,最终都会得到函数的定义。链接器不喜欢多个定义。但是,如果您将函数标记为inline
,则告诉编译器确保链接器将得到满足。
如何使链接器满意的真正方法取决于编译器和链接器,但在实践中,它归结为两种策略:
- 内联函数 - 这意味着函数定义实际上已从生成的代码中删除。相反,无论函数应该做什么,都将在调用函数的位置完成。
- 将函数标记为本地名称 - 链接器知道本地名称特定于特定文件,并且将始终将它们分开。
链接器将为每个包含标头的编译单元传递一个定义。
链接器将始终需要正好 1 个定义。
请考虑在一个源文件中定义函数,或者使用 inline
指令。
声明(.h)与定义(.c,.cpp...)不同
一个好的做法是在头文件中声明一个函数,在 guard 内部:
//file foo.h: can be included in other header or implementation files
#ifndef MY_HEADER
#define MY_HEADER
int MyFunction(int x);
#endif
并在实现文件中定义函数:
//file foo.c: not included in other files.
#include "foo.h" // to assert function declaration and definition match
int MyFunction(int x)
{
return x+1;
}
相关文章:
- MAKE:找不到包含的用户定义的头文件?
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 即使我没有包含多个文件,C++中的多个定义错误
- C2011: 'Card':"类"类型重新定义(尽管使用了包含保护并且没有在文件中重新定义.cpp类)
- 为什么更改包含 psapi.h 的顺序会产生编译错误?(标识符 BOOL 未定义)
- 生成文件缺少包含路径 尽管路径存在并已定义
- (Wix 安装程序)如何包含自定义操作依赖项
- 'dlopen''ing 包含符号的 .so 会导致未定义的符号
- 在Visual Studio代码中包含自定义c++库的问题
- 在 Visual Studio 2010(及更高版本)中定义包含或链接路径变量的位置
- 如何在C 中正确定义包含科学符号的整数矢量
- C++文件中正确的前向定义 C 包含
- 在C++中定义包含TTF_Font变量的向量时"Undefined size"错误
- 结构定义包含自身的静态实例
- 定义包含指向彼此的指针的类
- 如何定义包含int向量的sruct的少算子
- 调整定义/包含生成的结构以增强::融合
- C++正在重新定义包含的类
- CMake-在顶级CMakeLists.txt中定义包含路径和库
- 重新定义包含路径C++