选择和迭代语句的新块范围

时间:2014-10-13 10:16:53

标签: c

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

C11规范:

6.8.4:

  

选择语句是一个块,其范围是严格的子集   封闭区块的范围。每个相关的子语句也是一个   块的范围是选择范围的严格子集   言。

6.8.5

  

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

但如果我这样做:

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

GCC给我错误。

如何验证C99新规则?

有人能给我一些有用的例子吗?

2 个答案:

答案 0 :(得分:4)

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

  

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

表达式语句都不被视为声明(声明表达式至最严格)。您可以做的最好的事情是将声明放在{}括号内,例如:

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(见表格):

  

语法
  迭代语句:
  而(表达)陈述
  做声明而(表达);
  for(表达式 opt ;表达式 opt ;表达式 opt )语句
  for(声明表达式 opt ;表达式 opt )语句

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

答案 1 :(得分:1)

我读了一篇关于Straustrup的文章,他在那里讨论了C和C ++集成的问题。正如我们所看到的那样,似乎没有得到解决。甚至语句定义也有根本的不同。 在C中,if语句的控制表达式可能是表达式。例如,这句话

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

在C ++中有效,但类似的陈述

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

在C中不是v。

但无论如何你的if语句既不是C ++中的vaid也不是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