C++文件范围静态函数

C++ file-scope static functions

本文关键字:静态函数 范围 文件 C++      更新时间:2023-10-16

什么时候应该考虑使用在文件范围内定义的静态函数?

当在一个这样的函数中完成的任务并不真正属于任何类的成员函数时,以及当在某个源文件中只需要(重复)这样的任务时,我通常会使用它们。

我的用法是否符合此功能存在的原因?或者我是在劫持一个原本打算用于其他用途的概念?

这是对文件范围静态函数的一种非常有效的使用,但请记住,这种静态函数的使用已经被弃用了很长一段时间。通常更倾向于使用匿名名称空间。

如果函数和/或数据不是类接口的一部分,而是实现细节,那么我也会做类似的事情。

但我不使用关键字static。相反,我将函数和/或数据放在一个未命名的名称空间中。

首先,您要查找的术语是内部链接。您的问题应该是:"哪些实体应该具有内部链接?"static关键字或未命名的命名空间只是实现内部链接的实现机制。

现在答案应该是显而易见的:所有只需要在一个翻译单元内的实体都可以被赋予内部链接,这样做有好处:一是编译器可以利用任何其他翻译单元都看不到的信息,因此它可以避免发出可能需要的代码,或者更激进地内联。另一个原因是,如果您碰巧选择了一个在其他TU中也在本地使用的名称,则可以将意外ODR违规的风险降至最低。

一个典型的例子是这样的:

my_lib.hpp:

#ifndef H_MY_LIB
#define H_MY_LIB
namespace foo
{
    void do_an_awesome_thing(void * p, std::size_t n);
}
#endif

my_lib.cpp:

#include "my_lib.hpp"
namespace foo
{
    namespace
    {
        void helper(void * p) { /* ... */ }
        bool aux(std::size_t n, float f) { /* ... */ }
        constexpr char usage[] = R"(This is how you do it...)";
        constexpr float some_factor = 1.25;
    }
    void do_an_awesome_thing(void *p, std::size_t n)
    {
        if (!aux(n, some_factor)) { LOG_AND_DIE(usage); }
        helper(p);
    }
}

现在,您可以确保您的翻译单元不会对程序的其余部分造成任何不适当的链接时间负担。

放置未命名的名称空间是一个品味问题;您可以将它放在您通常的命名空间中,也可以放在顶级。效果是一样的。