当我根本不能将它放在头文件中时,为什么我应该声明一个静态的 "private" 函数?

Why should I declare a "private" function static when I can simply not put it in the header file?

我了解 static 关键字用于创建对翻译单元(源文件)而言 "private" 的函数或变量。

但是,据我所知,为了确保无法从声明的 .c 文件外部访问特定函数或变量,我可以简单地 not 在对应的.h文件中声明。

例如:

f.c

void public_func() {
    // ...
}

void private_func() {
    // ...
}

f.h

void public_func();

// no declaration of private_func

那么为什么我还要将 private_func 声明为 static?这仅仅是一个约定,还是比不在 .h 文件中声明它更具有技术优势?

假设您编写了一个包含多个 .c.h 文件的库。您的库的客户端将需要使用一些头文件来使用您的库。他们应该只能看到 public 函数。

但是对于你的库的实现,你也可以使用头文件,这样你的库中的函数就可以调用其他(内部)函数。

所以你最终得到两种类型的声明:

对于您图书馆的客户

void public_func();

供内部使用

static void private_func();

最好,私有和 public 声明在单独的头文件中,您的库的客户端只需要包含具有 public 函数的头文件。

问题是编译器在 "translation unit" 基础上工作,这意味着一个 .c 文件及其包含的所有 .h 文件。所以它传统上无法检测整个项目的命名冲突。

因此,如果您不将其设置为 static,则该函数默认具有 "external linkage"。这意味着如果有一个函数 private_func 并且同一项目中的另一个翻译单元使用相同的名称,则在链接和链接器错误期间会发生名称空间冲突。

这也是一个正确性问题 - private functions/variables 应该根本无法从外部访问,无论是有意还是无意。

I understand the static keyword is used for creating functions or variables which are "private" to the translation unit (the source file).

没错。

Is that simply a convention or does it have a technical benefit over simply not declaring it in the .h file?

这里有一个技术点。一旦编译器完成它的工作,它就会生成一个 object 文件。该文件有一个符号 table,当链接器将来自单独的 object 文件的程序放在一起时,链接器稍后会使用它。 static 函数不会进入那个 table,因此从其他 object 文件直接引用该函数将失败,并在链接阶段出现 "unresolved reference" 错误。

Benefits?好吧,你在 object 文件中保存了一些小的 space,链接阶段会进行得更快,因为要处理的 table 会更小。但这微不足道,不会产生任何影响,除非我们谈论的是一个由数千个名称很长的函数组成的案例。

如果您有一个非 static 函数并且您在 header 文件中省略了它的声明,函数名称仍然会进入符号 table。如果我碰巧以某种方式知道声明(除了来自 header)我仍然可以 call/reference 直接从另一个翻译单元的功能,不会发生链接器错误。