在编写标题库(如Boost)时,可以定义自由浮动(非方法)函数,而不会(1)膨胀生成的二进制文件和(2)产生“未使用”的警告吗?
当我在多个源文件包含的头文件中定义一个函数时,该文件又链接到同一个二进制文件中,链接器会抱怨重新定义。解决这个问题的一种方法是使函数保持静态,但这会在每个翻译单元中重现代码(顺便说一下,链接器可以安全地重复这些吗?)。此外,这会触发有关未使用函数的编译器警告。
我试图在Boost中寻找一个自由浮动函数的例子,但我找不到一个。是否可以在类(或模板)中包含所有内容?
答案 0 :(得分:12)
如果你真的想定义函数(而不是声明它),你需要使用inline
来防止链接器错误。
否则,您可以在头文件中声明该函数,并在源文件中单独提供它的实现。
答案 1 :(得分:8)
您可以使用inline
关键字:
inline void wont_give_linker_errors(void)
{
// ...
}
答案 2 :(得分:2)
呃......您的问题的答案只是 不 。你只是不定义头文件中的函数,除非它们是内联的。
'static'函数也可以在头文件中定义,但它仅对非常特殊的稀有目的有用。使用“静态”来解决多重定义问题完全是胡说八道。
同样,头文件用于非定义函数声明。为什么你想在地球上定义函数?
你说你正在写“标题库”。什么是“标题库”?请注意,Boost在头文件中定义了它的“函数”,因为它们的“函数”不是真正的函数,它们是函数模板。必须在头文件中定义函数模板(好吧,差不多)。如果情况并非如此,那么Boost就不会像在头文件中定义任何东西一样奇怪。
答案 3 :(得分:1)
除了已经提到的inline
之外,大多数编译器模板都必须在头文件中定义(并允许所有编译器使用)。由于boost主要是模板,这就解释了为什么它几乎都是标题。
答案 4 :(得分:-1)
人们已经建议inline
但是这违反了问题的第一部分,即随着在每次调用函数时将完整定义插入到代码中,它会使代码膨胀。因此,你的整体问题的答案是“不”。
如果您将它们标记为static
,那么它们仍然会在您正确指出的每个源文件中定义,但只有一次,因此这是比inline
更好的选项代码大小是唯一问题。我不知道链接器是否可以或者被允许发现重复项并将它们合并。我怀疑不是。
修改强>:
只是为了澄清我是否支持使用static
和/或在头文件中定义函数的概念的一般混淆,然后请放心,我不这样做。这仅仅是对头文件中定义的标记为inline
和static
的函数之间的差异的技术响应。没什么。