【问题标题】:Compilation implications of declaring all scope locals in the beginning as in early C?在早期 C 中一开始就声明所有作用域局部变量的编译含义?
【发布时间】:2013-12-18 23:35:22
【问题描述】:

我记得听说在 C 和 C++ 中不再推荐在块的开头排列所有范围成员的做法,但这是否意味着它在生成代码时会以某种方式阻碍编译器,或者只是说它不是再有必要这样做,因为它并不总是方便? A.K.A 如果按需声明局部变量,编译器生成最优分配是否更有效?

【问题讨论】:

  • 在 C++ 中,为有条件未使用的变量调用构造函数可能效率低下。在 C 语言中,我怀疑它是否会产生很大的实际差异,因为编译器可以判断地址是否取自变量,以及函数的哪些部分使用哪些变量。寄存器分配器/堆栈布局优化可以在可能的情况下重用插槽。但是,您可能会遇到一场关于它是否有助于在特定地方定义当地人的可读性的圣战。
  • 我不同意这个问题“主要基于意见”。他本可以问“我应该在哪里声明我的本地人?”,这将是基于意见的,但他问的是“我在哪里声明我的本地人对编译有何影响?”这是一个可以明确回答的问题。

标签: c++ c instantiation compiler-optimization locals


【解决方案1】:

过去在 C 中必须预先声明局部变量,大概是因为在这种情况下更容易实现编译器。

如今,编译器实际上“足够先进”,这对 POD 类型没有任何影响。因此,问题归结为 C 语言的可读性和品味问题。


然而,在 C++ 中,声明局部变量意味着相关构造函数和析构函数的执行,它可能会影响编译器是否能够使用某些优化。这意味着将它们全部声明在顶部并不等同于按需声明它们,从而使您的问题对 C++ 几乎无效。

在 C++ 中,如果变量在语义上对您尝试编写的程序是正确的,则声明变量。 (除此之外,还有可读性和品味的问题)

【讨论】:

  • C89 中的奇怪之处在于,您仍然可以在对象定义的初始化程序中混入任意表达式。所以这并不是说规则(到那时)允许编译器执行“计算堆栈上的内容”步骤,然后执行“发出代码”步骤,而不向后看。希望在 1985 年编写 C 编译器的人可以告诉我们为什么该规则使它变得更容易 :-) 此外,您可以在任何块的开头定义变量,而不仅仅是函数,因此它与函数堆栈无关这样的框架。
  • @SteveJessop 好吧,不难想象在 asm 的上下文中处理那些混合变量/表达式,前导码基本上只是将空间推入堆栈,然后是下一部分初始化它们...基本上运行该 C 代码两次,一次用于分配,一次用于初始化...但我什至不确定这不是流行的扩展,而不是语言标准。
猜你喜欢
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 2011-01-28
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多