【问题标题】:Placement of iterator declarations in C11 (coding style)C11 中迭代器声明的放置(编码风格)
【发布时间】:2014-05-09 05:25:55
【问题描述】:

我注意到 C11 不再允许您在循环构造中声明迭代器变量,例如,以下内容无效:

for (int i = 0; i < 10; ++i)

但这没关系:

int i;
for (i = 0; i < 10; ++i)

考虑到在 C99 之前甚至不可能在函数开头声明变量(块?Does C11 allow variable declarations at any place in a function?),我很好奇这与安全实践有何关系。迭代器应该声明在它们出现的函数或块的顶部,还是就在它们使用的第一个循环之上?我看不出这两种方式都有很大的不同,但前一种方法似乎更适合移动代码。就安全而言,我没有看到任何明显的影响。

另外,C11 发生上述变化的原因是什么?我更喜欢第一个示例中的语法。

编辑:对于我的最后一个问题,我想一个问题是,如果迭代器被多次使用,在一个块内移动 for (int i = 0; ... 将不会那么容易重构。

【问题讨论】:

  • 您在使用gcc -std=c11。如果您只使用 gcc 并且不指定标准,则默认为 gnu89,这不允许在 for 循环内声明。在 ANSI C、C89 中是这样的,但限制与“混合声明和代码”一起被删除
  • 我明白了,我没有使用那个选项。
  • 我以为我至少在使用 c99,因为我可以使用 stdbool.h。
  • 您必须为此指定-std=c99。通常,您应该指定 C 标准,因为如果不这样做,您将使用所有 gnu 扩展,从而限制了代码的可移植性。我不记得gnu89 支持哪些c99,但这足以引起问题。
  • 更多here

标签: c coding-style declaration c11


【解决方案1】:

你是从哪里得到这个想法的?

C11 draft,第 6.8.5 (1) 节说:

迭代语句

while表达式语句

语句 while (表达式) ;

for ( 表达式opt ; 表达式 opt ; 表达式opt ) 语句

for ( 声明 表达式opt ; 表达式 em>opt ) 声明

最后一种形式非常清楚地表明,for 语句的第一个子句中仍然允许声明。

[更新]

请注意,声明类似于int i = 0 ;。也就是说,它包括分号(参见第 6.7 节)。所以for (int i = 0 ; i &lt; 10 ; ++i)绝对是C11允许的。

[更新 2]

至于什么时候用哪个,那是见仁见智了。我的意见是尽可能嵌入声明,因为它使代码更易于阅读。

如果我正在阅读您的代码并且我看到了:

for (int i = 0 ; i < 10 ; ++i)
...

...那么我知道您在循环终止后不依赖i 的值,因为它不再在范围内。

如果我看到:

int i;
for (i = 0 ; i < 10 ; ++i)
...

...那么我希望你以后使用i的值;例如也许你很早就break 想知道i 是什么时候发生的。如果我以后没有看到你使用i,我可能会想知道你在想什么和/或我错过了什么。

像往常一样,可读性是最重要的指标。当然,什么是“可读”是见仁见智的问题。

【讨论】:

  • 整天在 GCC 和 MSVC 中工作。有一个警告需要提防。 i 的范围仅在 for{} 循环内。与往常一样,在哪里使用哪种形式需要一些判断。
  • @bbarker:总是告诉 gcc 你想编译什么 C 方言。见this question
  • 请注意:允许declaration expression 的表单也不允许expression-3
  • @david.pfx:我不这么认为... declaration 类似于int i = 0;... 也就是说,它包含分号。见附录 A.2.2。
  • @bbarker:该警告已过时。它应该是“C99 或 C11 模式”。试试gcc -std=c11 ...
【解决方案2】:

根据您链接的问题,C11 仍应允许您在 for 循环内声明变量(为什么它们会像那样破坏向后兼容性?)。

在任何情况下,如果您要针对 C89(Microsoft 编译器支持的 C 标准)进行编译,那么您只能在块的开头声明新变量(即:在花括号之后)。好消息是,您可以在任何地方放置一个新块,而不仅仅是在函数的顶部,因此您可以通过将其包装在一组额外的花括号中来模拟 C99 for 循环范围:

/* ... */
{int i; for(i=0; i<10; i++){
    /* ... */
}}
/* ... */

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    相关资源
    最近更新 更多