代码之家  ›  专栏  ›  技术社区  ›  Aviv Cohn

为什么我要声明一个“private”函数static,而我却不能把它放在头文件中?

  •  1
  • Aviv Cohn  · 技术社区  · 7 年前

    我明白 static 关键字用于创建对翻译单元(源文件)是“私有”的函数或变量。

    .c 我可以简单地 在相应的 .h 文件。

    void public_func() {
        // ...
    }
    
    void private_func() {
        // ...
    }
    

    f、 小时

    void public_func();
    
    // no declaration of private_func
    

    private_func 作为 静止的 ? 这仅仅是一个公约,还是它有一个技术上的好处,而不是简单地不宣布它在美国 h

    2 回复  |  直到 7 年前
        1
  •  3
  •   Lundin    7 年前

    问题是编译器是以“翻译单元”为基础工作的,即一个.c文件及其包含的所有.h文件。因此,传统上无法检测整个项目中的命名冲突。

    所以如果你不能成功 static ,该函数默认具有“外部链接”。意思是如果有一个函数 private_func 而同一项目中的另一个翻译单元使用相同的名称,则在链接和链接器错误期间会出现命名空间冲突。

    这也是一个正确性的问题-私有函数/变量不应该只是从外部访问,无论是有意还是无意。

        2
  •  1
  •   Igor S.K.    7 年前

    我知道static关键字用于创建对翻译单元(源文件)是“私有”的函数或变量。

    那是真的。

    这仅仅是一个约定,还是相对于不在.h文件中声明它有技术上的好处?

    这里有一个技术要点。一旦编译器完成了它的工作,它就会生成一个对象文件。该文件有一个符号表,当链接器将来自不同对象文件的程序放在一起时,链接器会使用该符号表。 static 函数将不会进入该表,因此从其他对象文件直接引用该函数将失败,并在链接阶段出现“未解析引用”错误。

    Benefits ? 如果在对象文件中节省一些小空间,链接阶段会更快,因为要处理的表会更小。但这很小,不会有什么区别,除非我们讨论的是一个虚构的案例,有成千上万个函数的looong名字。

    如果你没有- 如果在头文件中省略它的声明,函数名仍然会进入符号表。如果我碰巧以某种方式知道声明(而不是从头部),我仍然可以直接从另一个翻译单元调用/引用函数,不会发生链接器错误。

        3
  •  0
  •   Codo    7 年前

    假设您编写了一个由多个 .c .h 文件夹。库的客户端需要使用一些头文件才能使用库。他们应该只看到公共职能。

    因此,您将得到两种类型的声明:

    void public_func();
    

    供内部使用

    static void private_func();