不使用无类函数的 "inline" 或 "static" 关键字时,C++ 重新定义 link 错误
C++ redefinition link error when not using "inline" or "static" keywords with classless functions
所以我意识到,当包含一个“.h”文件时,编译器实质上是将该文件的内容复制到它被包含的位置。所以很明显,如果我在许多文件中包含 "Utils.h",如果 utils.h 包含函数实现,则会导致重新定义错误。
我还意识到使用 inline
关键字可以解决这个问题,方法是从根本上消除该函数并将其内联到它的使用位置。
现在我的问题是,当在头文件中使用 static
关键字时,它似乎也解决了问题,但我不确定我是否完全理解 why/how 它解决了问题...?据我了解,cpp 文件中的 static 本质上会使它仅在该编译单元中可用。
为确保我们都在同一页面上,这里有一段相关代码:
//Utils.h (included in many places)
namespace utils {
void someUtil() {
//do work
}
}
上面会抛出错误的地方,但是使用 static
and/or inline
关键字,就不会有问题。
所以我想知道 static 在这种情况下做了什么,如果它是一个小函数体或...,我应该使用它还是内联?
static,告诉编译器在定义它的每个翻译单元中生成函数,只是不共享它。因此,如果您在许多翻译单元中使用,并且如果您在不同的 TU 中检查函数的地址,您将得到不同的结果。
inline 另一方面的功能:
There may be more than one definition of an inline function or
variable (since C++17) in the program as long as each definition
appears in a different translation unit and (for non-static inline
functions and variables (since C++17)) all definitions are identical.
For example, an inline function or an inline variable (since C++17)
may be defined in a header file that is #include'd in multiple source
files.
因此编译器将内联调用该函数,或者将来自不同 TU 的函数定义合并在一起(以便生成的函数在可执行文件中存在一次)。
因此在您的情况下,内联就是您所需要的。
所以我意识到,当包含一个“.h”文件时,编译器实质上是将该文件的内容复制到它被包含的位置。所以很明显,如果我在许多文件中包含 "Utils.h",如果 utils.h 包含函数实现,则会导致重新定义错误。
我还意识到使用 inline
关键字可以解决这个问题,方法是从根本上消除该函数并将其内联到它的使用位置。
现在我的问题是,当在头文件中使用 static
关键字时,它似乎也解决了问题,但我不确定我是否完全理解 why/how 它解决了问题...?据我了解,cpp 文件中的 static 本质上会使它仅在该编译单元中可用。
为确保我们都在同一页面上,这里有一段相关代码:
//Utils.h (included in many places)
namespace utils {
void someUtil() {
//do work
}
}
上面会抛出错误的地方,但是使用 static
and/or inline
关键字,就不会有问题。
所以我想知道 static 在这种情况下做了什么,如果它是一个小函数体或...,我应该使用它还是内联?
static,告诉编译器在定义它的每个翻译单元中生成函数,只是不共享它。因此,如果您在许多翻译单元中使用,并且如果您在不同的 TU 中检查函数的地址,您将得到不同的结果。
inline 另一方面的功能:
There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.
因此编译器将内联调用该函数,或者将来自不同 TU 的函数定义合并在一起(以便生成的函数在可执行文件中存在一次)。
因此在您的情况下,内联就是您所需要的。