【问题标题】:Why before ALL functions (except for main()) there is a 'static' keyword?为什么在所有函数(main() 除外)之前都有一个“静态”关键字?
【发布时间】:2010-02-07 21:54:12
【问题描述】:

我正在阅读一些 C 和 C++(主要是 C)的源代码文件... 我知道“静态”关键字的含义是静态函数是仅对同一文件中的其他函数可见的函数。在另一种情况下,我读到在我们不希望在它们编写的文件之外使用静态函数的情况下使用静态函数很好......

正如我之前提到的,我正在阅读一个源代码文件,我看到所有函数(除了主函数)都是静态的......因为没有其他附加文件与主源代码 .c 文件链接(不是甚至标题),从逻辑上讲,为什么我应该将静态放在所有功能之前?当只有 1 个源文件时,它们应该受到什么保护?!

编辑:恕我直言,我认为这些关键字只是为了让代码看起来更大更重..

【问题讨论】:

  • 恕我直言,c 中的 static 应该是默认值。您应该始终寻求最高级别的隔离,并且仅在需要时才重新使用它。放松不是一个突破性的变化,而如果你忘记隔离并且有人开始使用你的代码,那么加强就会如此。
  • 我个人并不关心,但有些人会因为你没有接受任何答案而感到不安。您可以返回并这样做以表明您的问题已得到解答,或者编辑您的问题以让人们知道您仍然想知道什么。

标签: c static


【解决方案1】:

如果函数是extern(默认),编译器必须确保它始终可以通过其外部可见符号调用。

如果一个函数是static,那么这给了编译器更多的灵活性。例如,优化器可能决定内联一个函数;使用static,编译器不需要生成额外的离线副本。此外,符号表会更小,可能也会加快链接过程。

而且,这只是一个养成的好习惯。

【讨论】:

    【解决方案2】:

    很难单独猜测,但我的假设是它是由某个人编写的,他假设在某个时候可能会添加更多文件(或此文件包含在另一个项目中),所以为代码的运行提供了最少的必要访问。本质上将公共 API 限制在最低限度。

    【讨论】:

      【解决方案3】:

      但是还有其他文件与您的主模块相关联。

      事实上,图书馆中有数百甚至数千个。其中大部分不会为小程序选择,但链接器会扫描所有符号。 main 中的符号和从库中导出的符号之间的冲突本身不会造成任何伤害,但想想意外命名 strcpy() 可能会导致的麻烦。

      此外,习惯最佳实践风格可能没有什么坏处。

      【讨论】:

        【解决方案4】:

        作为我遵循的编码规则,在其源文件之外可见的任何函数(main() 除外)都需要声明,并且该声明应位于标头中。我尽可能避免在我的源文件中为函数编写“外部”声明,而且几乎总是可以的。

        如果一个函数只在单个源文件中使用,它应该是静态的。这使得修改更容易;您知道唯一需要查看的地方就是您现在面前的源文件(除非您习惯将 '.c' 文件包含在其他 '.c' 文件中 - 这是也是一个坏习惯,现在应该改掉)。

        我使用 GCC 来帮助我执行编码规则:

        gcc -m64 -Wall -Wextra -std=c99 -Wmissing-prototypes -Wstrict-prototypes
        

        这是一个相当典型的标志集合;我有时使用-std=c89 而不是-std=c99;我有时使用-m32 而不是-m64;我并不总是使用-Wextra(但我的代码正朝着那个方向发展)。我总是使用-Wmissing-prototypes-Wstrict-prototypes 来确保每个外部函数在定义或使用之前声明(并且每个静态函数在使用之前声明或定义)。我偶尔会使用-Werror(所以如果编译发出警告,编译就会失败)。我可以比我更多地使用它,因为我的代码在没有警告的情况下编译 - 或者得到了修复。

        所以,您很容易就能看到我的代码。在我的代码中,唯一公开的函数(即使在单个源文件程序中)是在标头中声明的函数,这意味着它们是源文件所代表的模块的外部接口的一部分。

        【讨论】:

          【解决方案5】:

          可能是作者采取了预防措施。例如,如果其他人将此文件用作源,则将此文件包含在他的主文件中。

          【讨论】:

          • @Pavel - 啊,是的;敢于回答问题 - 一个明显的迹象。
          • @Pavel - 我认为不回答问题,仅仅因为你可能不拿一些分数是“wh*ring”。我是来学点东西的,不是来挑分数的!
          • 好吧,我可以回答这个问题,但我不会。检查我的代表图并思考为什么二阶导数小于零。 gl.
          • 我不在乎......如果你不想回答 - 就不要回答。没有理由粗鲁,用缺点拍打。
          【解决方案6】:

          因为没有其他额外的 与主要源代码链接的文件 .c 文件(甚至不是标题),逻辑上 为什么我要把静态放在首位 职能 ?他们应该是什么 只有 1 个来源时受保护 文件?!

          在这种情况下,您确实不需要 static 关键字。

          编辑:恕我直言,我认为这些关键字只是为了使代码看起来更大更重..

          但是,如果您真的想了解更多关于 static 关键字的信息,您可以从一本书开始。 #2216239 上的关键字 static 的更多信息——可能会有所帮助!

          【讨论】:

          • 好的,现在是时候讨论双重反对票了。有人可以解释这篇文章有什么问题吗?我指的是我的另一个 SO 答案。不是博文。
          • 我猜人们反对“在这种情况下你真的不需要静态关键字”部分答案。在那一点上,它变得接近狂热;我自己使用静态,即使在单源文件程序中,但我不要求其他人都这样做。我想人们可能会反对交叉引用的“无耻插件”部分。也许如果它被改写,那会改变事情。我怀疑你正在遭受“雷鸣般的羊群效应”;一旦发生没有评论的反对票,其他人就可以轻松跟进。讨厌!
          • 我没有对你投反对票。但是“不需要”!=“应该摆脱”。
          • @Jonathan 和 litb:已编辑帖子。另外,如果不清楚,不,我不是要建议任何一种方式,除了在单个文件玩具程序中,您可以取消statics。
          猜你喜欢
          • 1970-01-01
          • 2017-08-02
          • 2020-10-09
          • 1970-01-01
          • 2010-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-17
          相关资源
          最近更新 更多