【问题标题】:Is there any benefit from declaring variables at the beginning of a function?在函数开头声明变量有什么好处吗?
【发布时间】:2021-03-06 15:50:18
【问题描述】:

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

【问题讨论】:

  • 这感觉有点基于意见。话虽如此,为了清洁,我总是建议只从需要它们的地方声明变量。如果您只需要在单个块中使用变量,为什么要在该块之外声明它?
  • @ThomasJager:有一些编码标准,其中 MISRA 是最常见的,它不允许混合代码和声明。但是,我同意这太宽泛了,应该关闭。我认为你应该有足够的代表来近距离投票?
  • @toohonestforthissite 您能否指出具体的 MISRA 规则,该规则要求仅在函数或块范围的开头声明变量?
  • 这个意见的依据是什么。我要事实,而不是意见。事实证明,不,没有真正的速度或性能方面的好处。不知道为什么你们总是将内容标记为基于意见。
  • 这个问题中唯一基于意见的是 cmets。

标签: c c99


【解决方案1】:

答案是否定的。在函数开头声明标识符并没有编译或其他计算方面的好处。

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

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

【讨论】:

    【解决方案2】:

    C 语言允许在至少 1978 年的任何语句块中声明变量,如The C Programming Language 第 4.8 节块结构中所述。这也在Where you can and cannot declare new variables in C? 中有所描述。

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

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

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

    相反,我可以想到几个原因,说明这样做没有好处:

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

    【讨论】:

    • 这不是问题所在。混合代码和声明确实是从 C99 开始才被允许的。在那之前,声明只允许在块的开头(旁注:块 is 本身就是一个语句。语言中不存在“语句块”)。仅供参考:放宽这一点的最明显原因是 VLA,出于可靠性原因,它要求在声明之前检查长度。
    • @tooHonest for this site OP 询问在函数开头以外声明变量是否有用。我指出自 K&R C 以来就已支持这一点。没有迹象表明这是关于在文本中内联声明变量,只是在函数内的多个位置。我已将您的其他用例添加到答案中。
    • 我并没有说您添加了更多信息,只是您对标准的陈述不完整并且对初学者具有误导性。 OP 明确询问了混合代码和声明,这绝对不仅仅是在块开始时的声明,而是我指出的。写你的编辑:C没有堆栈的概念,更少的堆栈框架。你甚至不会在标准中找到那个词。所以引用“堆栈帧变量”是没有意义的。这甚至不是一个常见的术语。您的意思是广泛使用的“自动”或 自动 变量。
    • @tooHonest for this site 您对答案的更正将继续受到赞赏并改善结果。我不明白你怎么不能合理地解释“一个分支需要一个变量”来表示块开始处的声明。
    • 很好的尝试把它从上下文中拉出来。完整的句子是“(例如在 if 语句中,一个分支需要一个变量)但第二个不需要)”。如果括号不足以作为指标,这只是一个例子,“例如”应该很明显。还是不同意? (哦,它甚至没有说明需要在块的开头声明变量 - 甚至没有挑剔“分支”一词是非标准和模棱两可的)
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 2012-10-20
    • 2019-03-27
    • 1970-01-01
    相关资源
    最近更新 更多