【问题标题】:Can't have label on mid-stream declaration in C?C 中的中游声明不能有标签吗?
【发布时间】:2016-08-20 01:43:53
【问题描述】:

所以这在 C99 中:

label:
  int ret = function(of, stuff);

给出一个编译时错误,而这个:

label:
  ;
  int ret = function(of, stuff);

工作得很好。

这是编译器错误吗?或者这是 C 标准定义中的错误?或者如果这是 C99 标准的一部分,也许有人会站出来为 C 标准辩护,声称这是完全合理的?

【问题讨论】:

  • “也许有人会站出来为 C 标准辩护,声称这是完全合理的”——好吧,你肯定来对地方了。
  • 为什么这些票数接近...... :-S - 一个公平的问题,我仍然记得很清楚...... :-)
  • 显然有关编程语言的问题与编程无关?

标签: c standards c99 goto


【解决方案1】:

标签,在N1256 6.8.1 标签语句中定义,只能包含语句

 Syntax  
1      labeled-statement:  
           identifier : statement  
           case constant-expression : statement  
           default : statement

int ret = function(of, stuff); 是一个声明,它在 N1256 6.7 声明中定义,不是声明。

语句在 N1256 6.8 语句和块中定义如下:

 Syntax
1      statement:
           labeled-statement
           compound-statement
           expression-statement
           selection-statement
           iteration-statement
           jump-statement

compound-statement就是所谓的blocks,就是被{}包围的0个或多个声明和语句。

expression-statement 是在 N1256 6.5 表达式中定义的零个或一个表达式,后跟一个分号,如 i++;。语法中的表达式在 N1256 6.5.17 逗号运算符中定义。

selection-statementifswitch 语句。

iteration-statementwhiledo-whilefor 语句。

jump-statementgotocontinuebreakreturn 语句。

如您所见,声明不是声明,因此您不能为声明添加标签。

【讨论】:

  • 所以你可以有例如。 label: {int ret = function(of, stuff); }.
【解决方案2】:

可以说是规范中的一个错误——当它被更改为允许将语句和声明混合在一个块中(而不是要求所有声明在语句之前)时,它也应该被更改为允许在声明中添加标签,但是不是。语言如何随时间演变的产物。

这不是您发现的主要问题,因为您可以通过将标签放在声明之前的空语句上来轻松解决它。

【讨论】:

  • 也许,但请注意,对于开关中的尾随案例(或标签),相同的小问题和解决方法早于 C99。我猜想需要一个成功的语句可以解决一些歧义,或者让解析器的工作更轻松。
  • 如果禁止声明后面的声明的目的实际上是为了确保在不离开声明范围的情况下不可能从声明之后的点跳转到声明之前的点,我不会感到惊讶该声明。要求 function 中的所有变量都在任何可执行代码之前(正如一些 C89 之前的编译器所做的那样)简化了代码生成,但我认为 C89 规则并没有提供任何真正的优势,除了确保代码在声明必须离开其范围之前将控制权转移到某个点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2020-07-22
  • 1970-01-01
  • 2012-02-04
相关资源
最近更新 更多