在函数开头声明变量有什么好处吗?

Is there any benefit from declaring variables at the beginning of a function?

我知道 C99 之前的编译器需要在函数开头声明变量以计算堆栈大小。然后取消了要求。如今,除了向后兼容之外,仍然坚持该方案是否有任何好处,或者也许是仅在需要时以及在更需要它们的地方声明变量? (例如在 if 语句中,其中一个分支需要一个变量而第二个分支不需要)

答案是否定的。在函数开头声明标识符没有编译或其他计算优势。

优秀的现代编译器会分析值在代码中的使用位置,因此声明的位置无关紧要,只要它们不影响语义(例如将声明移动到复合语句中,缩小其范围)。

在某些情况下,在函数或块的开头告诉 reader 您将要做什么可能会有好处。通常,在需要的地方声明标识符是有益的,因为这往往会减少 reader 一次必须考虑的事情的数量。但是,如果某个函数将要执行的算法有某种模式或韵律和原因,那么在开头展示它的某些方面可以帮助 reader 理解它。

至少从 1978 年开始,C 语言就允许在任何语句块中声明变量,如 The C Programming Language Section 4.8 Block Structure. This is also described in Where you can and cannot declare new variables in C? 中所述。

最近的修订除了允许在任何块的开头进行声明外,还允许将声明放在块的后面,但不允许前向引用。数组的大小也可以动态定义,不局限于常量表达式。

是否有任何好处打开了对谁的问题。我能想到有好处的原因:

  • 更简单的函数可能无法从变量声明结构化的额外设计工作中获益,
  • 具有局部作用域变量的函数可以默默地隐藏更高级别的声明,
  • 包含动态大小调整的自动变量声明需要在分配前进行检查,
  • 代码的读者可以在一个位置看到函数中引用的标识符——通常带有描述行为的注释,并且
  • 从没有此功能的其他语言翻译的代码看起来更像原始代码。

相反,我可以想到这没有好处的几个原因:

  • 天真的编译器可以使用此信息来改进堆栈帧分配而无需静态分析(特别是对于大变量),
  • 机械代码生成器可以通过在较小范围内声明变量而无需检查来避免名称 space 冲突,并且,
  • 长函数通过避免在整个函数体中可能使用无效的值而受益于局部作用域。