在头文件中实现的函数的static与inline
static vs inline for functions implemented in header files
我认为C++中的inline
用于链接/作用域。我把它和全局对象的extern
和static
放在同一个篮子里。
通常,对于在头文件中实现的函数,我的首选解决方案是使其静态:
// In Foo.h
static void foo()
{
// Do stuff...
}
然而,我相信这也是有效的,似乎没有违反ODR:
// In Foo.h
inline void foo()
{
// Do stuff...
}
两者在语义上有什么区别?此外,我也不确定C++标准的哪些领域可以解释确切的差异,或者它是否只是未定义的,差异在于实现。
inline
准确地传达了您想要的内容:"请取消此函数的ODR(一个定义规则),以便每个翻译单元可以(也必须)提供自己的函数定义副本"。
然后,编译器将内联调用该函数,或者将来自不同TU的函数定义合并在一起(以便生成的函数在可执行文件中存在一次)。
另一方面,static
告诉编译器在定义该函数的每个翻译单元中生成该函数,而不是共享该函数。因此,最终可执行文件中存在任意数量的技术上独立的函数。
简而言之,如果您使用static
,那么在不同的转换单元中获取函数的地址将返回不同的地址(因为您告诉编译器在每个TU中生成一个函数),但如果您使用inline
,它们将显示相同的地址(由于您定义了一个函数,并只是告诉编译器将许多定义合并在一起)。
主要区别在于函数中的任何静态局部变量会发生什么——如果函数是static
,那么每个编译单元都将有自己的静态局部变量副本,这与任何其他编译单元都不同。如果函数是inline
,那么所有编译单元将只共享一个(一组)静态本地。
在许多情况下,您不会注意到差异,因为编译器和链接器现在非常聪明。但是,内联函数的行为必须像它是一个正则函数一样。头中的静态函数将被编译到包含它的每个源文件中,因此会有很多它的副本
大多数情况下,这并不重要,但也有一些方法可以做到。内联函数有一个地址。静态函数在每个翻译单元中都有不同的地址。
静态局部变量:在内联中,将有它们的单个副本。对于静态函数,对于包含该函数的每个翻译单元,每个静态局部变量都将有一个唯一的副本。
从关键字inline
和static
的原意来思考这个问题可能会更有帮助,也更清晰。
- 内联函数
关键字inline
的初衷是提高运行时性能,而不是像您一开始所说的那样用于链接/作用域。这是一个提示,使编译器尝试在调用点内联生成代码,而不是一次编写代码并每次调用它,这样可以避免一些开销,例如为调用创建堆栈帧。为了生成内联代码,函数定义必须在范围中,而不仅仅是像普通函数那样的声明。因此,您应该将整个函数定义放在一个头文件foo.h
中,调用它时放在#include "foo.h"
中。这些位于不同翻译单元中的inline
函数必须逐个令牌相同,才能遵守ODR(一个定义规则)。所有的inline
函数都是一个函数,这个inline
函数中的static
变量也是如此。
- 静态函数
关键字static
可用于使函数成为翻译单元的本地函数,也就是说,它赋予它们内部链接。因此,如果将foo()
的整个函数定义放入头文件foo.h
中,并将其标记为static
,则#include "foo.h"
的所有翻译单元都将具有本地函数foo()
。换句话说,不同翻译单元中的函数foo()
不是一个单一的函数,这些static
函数中的static
变量也不是。
- 静态内联函数
因此您可以猜测由static
和inline
标记的函数。这些函数不像static
函数那样在不同的翻译单元中是相同的,但可以通过内联生成代码来提高性能。
似乎没有人提到在C++中,静态函数是直接调用的函数,而不是在类的实例上调用的函数。换句话说,不存在隐含的"this"指针。如果类MyClass的函数foo是静态的,那么您说:
MyClass::foo();//称之为
而不是:MyClass an_object=新建MyClass();an_object->foo();
- 数组在 C++ 中不使用 static in 函数时不会修改
- 为什么静态成员函数定义不能有关键字"static"?
- C++不使用"inline"或"static"无类函数的关键字时出现重定义链接错误
- 使用 static int 返回 int&in 函数
- 在头文件中实现的函数的static与inline
- 重置"static"类的函数的命名约定
- 在方法/函数中使用"static const std::string"还是只使用"cons
- 静态函数错误LNK2001:未解析的外部符号"private: static int B::s_nValue"
- 为什么 C++ 不接受函数定义中的 static 关键字
- 类或函数模板"static-if"更好?
- *static*成员函数的常量和非常量版本
- 使用static函数初始化static const int
- 何时应在非成员函数之前编写关键字 'static'?
- 使用static在函数中存储数组各个组件的值
- 为什么在 C++ 中将函数作为参数传递给 pthread 时会出现"non-static member function"错误?
- 使用static防止函数内的多个副本
- 函数指针生成'invalid use of non-static member function'错误
- 在[expr.static.cast]/4中,术语"一个可行函数"指的是什么
- 使用 "static virtual" 函数的元对象
- C++中是否有"static class",例如要在同一文件中访问的静态函数?