当我不能将它放在头文件中时,为什么我应该声明一个“私有”函数静态?

问题描述 投票:2回答:3

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

但是,据我所知,为了确保某个特定的函数或变量不能从声明它的.c文件外部访问,我只能在相应的.h文件中声明它。

例如:

F.C

void public_func() {
    // ...
}

void private_func() {
    // ...
}

f.h

void public_func();

// no declaration of private_func

那么我为什么还要将private_func声明为static?这只是一个惯例,还是仅仅在.h文件中没有声明它有技术上的好处?

c header-files private
3个回答
3
投票

问题是编译器在“翻译单元”的基础上工作,这意味着一个.c文件和它包含的所有.h文件。因此传统上无法检测整个项目中的命名冲突。

因此,如果你没有使它成为static,该函数默认为“外部链接”。意味着如果在同一个项目中有一个函数private_func和另一个转换单元使用相同的名称,则在链接和链接器错误期间会出现命名空间冲突。

这也是一个正确的问题 - 私人职能/变量应该无法从外部访问,无论是有意还是无意。


1
投票

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

确实如此。

这仅仅是一个约定,还是仅仅因为没有在.h文件中声明它而具有技术优势?

这里有一个技术问题。编译完成后,它会生成一个目标文件。该文件具有符号表,当链接器将程序从单独的目标文件放在一起时,链接器稍后使用该符号表。 static函数不会进入该表,因此从其他目标文件直接引用该函数将失败,并在链接阶段出现“未解析的引用”错误。

Benefits?那么你在对象文件中保存了一些小空间,链接阶段会更快,因为会有一个较小的表来处理。但这足够小,不会产生任何影响,除非我们谈论的是数千个具有loooong名称的函数的组合案例。

如果你有一个非static函数,并且在头文件中省略了它的声明,那么函数名仍会进入符号表。如果我碰巧以某种方式知道声明(除了从头部开始),我仍然可以直接从另一个转换单元调用/引用该函数,不会发生链接器错误。


0
投票

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

但是对于库的实现,您可能还使用头文件,因此库中的函数可以调用其他(内部)函数。

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

对于您图书馆的客户

void public_func();

供内部使用

static void private_func();

优选地,私有和公共声明位于单独的头文件中,并且库的客户端只需要包含具有公共函数的头文件。

© www.soinside.com 2019 - 2024. All rights reserved.