【问题标题】:Change default from Extern to Static将默认值从外部更改为静态
【发布时间】:2013-01-23 22:44:32
【问题描述】:

我总是忘记在我的变量和函数中添加“静态”前缀,因此 GCC 将它们标记为外部。是否可以更改此行为,以便默认情况下将所有内容标记为静态。并且这两种类型在运行时是否存在性能差异,还是更像是一种形式?

【问题讨论】:

  • 您可能想从编译后的代码中转储符号,以查看是否有任何您忘记将其设为静态的内容。试试nmobjdump 和其他类似的工具。

标签: c gcc static c99


【解决方案1】:

是否可以更改此行为,使其默认将所有内容标记为静态。

据我所知。

这两种类型在运行时是否存在性能差异,还是更多的形式?

是的,gcc 能够在指定对象或函数static 时执行进一步优化。例如,gcc(即使在-O0 中)将内联一个只调用一次的static 指定函数。

【讨论】:

  • 您知道 GCC 是否会检测到该变量未在其他文件中使用,并在编译时将其视为静态变量?还是我总是需要显式添加它?
  • @Joshua 不会的。或者至少不是默认情况下。较新的gcc 版本具有链接时间优化:请参阅gcc 选项-flto-fwhole-program
【解决方案2】:

首先:extern 修饰符不是默认值。该限定符表示所提及的项将在另一个编译单元中定义,因此它仅适用于声明全局变量之类的内容。

无法将static 修饰符设为默认值,因为没有dynamic 修饰符可以取消此默认值。因此,没有办法使用该默认值编写工作代码:每个函数和变量都是static,这将导致编译器生成一个空的输出文件!

这两种类型在运行时是否存在性能差异,还是更像是一种形式?

编译器可以对static 函数和变量执行一些不能在动态函数和变量上执行的优化。特别是,static 函数和从未被引用的变量可能会被完全删除,static 函数可以更积极地内联。

【讨论】:

  • 如果 extern 不是默认值,那么默认值是什么?
  • 默认为空(即无修饰符)。静态变量没有链接——它们不能被其他文件引用。
  • 那么'nothing'和extern有什么区别呢?因为听起来他们提供的东西是一样的。默认情况下没有使用静态选项似乎很奇怪,因为与我需要它们为静态的时间相比,我需要从其他文件访问全局变量的时间要少得多。希望 GCC 足够聪明,能够在编译时注意到该变量没有在其他任何地方使用,并将其编译为静态。
  • 记得在前面输入静态! ;)
  • 区别:extern 只生成链接,不生成存储。 GCC 无法检测到变量没有被外部引用,因为它一次只查看一个 C 文件。到链接发生时,静态化任何东西都为时已晚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-04
  • 2019-09-03
  • 2021-03-26
  • 2014-05-16
  • 2017-08-26
相关资源
最近更新 更多