【问题标题】:New block scope for selection and iteration statement选择和迭代语句的新块范围
【发布时间】:2014-10-13 10:16:53
【问题描述】:

在 C99 中,对于迭代语句和选择语句,有新的块作用域,我知道 ifwhile 等本身是块作为它们的子语句,也没有 { }

C11 规范:

6.8.4:

选择语句是一个块,其范围是 其封闭块的范围。每个关联的子语句也是一个 范围是选择范围的严格子集的块 声明。

6.8.5

迭代语句是一个块,其范围是一个严格的子集 其封闭块的范围。循环体也是一个块,其 范围是迭代语句范围的严格子集。

但如果我这样做:

if( (int a = 10) == 10 ) // error: expected expression before '==' token
   int j = 10; // error: expected expression before 'int'

GCC 给我错误。

如何验证 C99 新规则?

谁能给我一些工作示例?

【问题讨论】:

  • 具体是哪条规则?
  • @2501,我用规范规则编辑了问题。

标签: c


【解决方案1】:

C 语言的语法根本不允许您尝试完成的工作。 N1570 §6.8.4/p1:

语法
选择声明:
if ( 表达式 ) 语句

expressionstatement 都不被视为声明(declaration expression 最好严格)。您可以做的最好的事情是将声明放在{} 括号内,例如:

int a = 10;
if (a == 10) {
    int j = 10;
}

标准允许的唯一情况(实际上是由 C99 引入的)是在 for 循环中放置声明而不是初始化表达式:

for (int a = 0, b = 0; a + b < 20; a++, b++) {
    int j = 10;
}

对此的参考是 §6.8.5/p1(见第四种形式):

语法
迭代语句:
while ( 表达式 ) 语句
do 语句 while ( 表达式 ) ;
for ( 表达式opt ; 表达式opt ; 表达式opt ) 语句
for ( 声明表达式opt ; 表达式opt ) 语句

这里真正的问题是,如果您不能将其与声明表达式一起使用,那么 if 语句(截至 §6.8.4/p5)的单独作用域的目的是什么。您会看到只有for 循环才有可能。

【讨论】:

    【解决方案2】:

    我阅读了 Straustrup 的一篇文章,他讨论了 C 和 C++ 的集成问题。正如我们所看到的,问题似乎尚未解决。甚至语句定义也有根本的不同。 在 C 中,if 语句的控制表达式可能只是一个表达式。因此例如这个语句

    if ( const char *p = std::strchr( "Hello", 'H' ) ) { /*...*/ }
    

    在 C++ 中有效,但类似的语句

    if ( char *p = strchr( "Hello", 'H' ) ) { /*...*/ }
    

    在 C 中不可用。

    但无论如何,您的 if 语句在 C++ 和 C.:) 中都无效:)

    if( (int a = 10) == 10 )
    

    可以是表达式或声明。来自 C++ 标准

    condition:
    
    expression
    attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
    attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      相关资源
      最近更新 更多