【问题标题】:Why is a semicolon by itself allowed in C/C++? [duplicate]为什么在 C/C++ 中允许使用分号? [复制]
【发布时间】:2015-12-02 21:42:57
【问题描述】:

为什么C/C++解析器单独使用分号不报错?例如:

int a;
;
int b;

这是语言语法规则的结果还是解析算法的结果?标准对这种情况有什么看法?无论是; 还是例如int; 应该被允许吗?

【问题讨论】:

  • int; 不允许,因为定义缺少标识符。
  • 为什么不允许;
  • ;空语句
  • 在 C++ 中什么都不做并不违法。 :)
  • 还有非常相似的Use of null statement in C中有趣的答案

标签: c++ c parsing language-lawyer


【解决方案1】:

分号结束语句。

如果你的语句没有做任何事情,那是你作为程序员的特权。

空语句的完全有效使用示例:

 for (int x = 0;; x++) {
     if (something(x)) {
         return 5;
     }
     if (bah(x)) {
         continue;
     }
     if (otherthing(x)) {
         return 3;
     }
 }

for 循环中的中间语句为空。但它仍然是必要的,因为for 循环需要三个不同的语句,并且第一个和第三个被填充。

我看不出一个单独的分号应该无效的充分理由;它没有害处。所有相关的 C/C++ 标准都允许这样做,这并不比不被允许更糟糕。

【讨论】:

  • 1. 所有标准都允许吗? (甚至是 C++11 之前的版本?)IIRC 不是。
  • @LuchianGrigore 在循环的顶部。 for (int x = 0;; x++)。注意双分号。
  • @LuchianGrigore - 空语句在for (int x = 0;; x++) - 注意两个分号连续,这是一个空语句。据我所知,答案中给出的示例在所有 C 和 C++ 标准以及 K&R 中均有效。
  • @LuchianGrigore 如果 C98 不允许,那么我一生中从未见过符合标准的编译器。我还没有一个程序被拒绝,因为它在行尾包含一个额外的分号。
  • 我不想这么说,但你的 for 循环不包含空 (null) 语句。它仅包含一个缺失条件。要查看它,请考虑您不能将语句放在那里(但只能是类型可以转换为布尔值的表达式或声明的条件)。类似的只是在空语句和缺失条件中,都缺失了一个可选的表达式,仅此而已。
【解决方案2】:

考虑来自 K&R 的经典字符串复制功能:

void strcpy(char *src, char *dst)
{
    while (*src++ = *dst++);
}

如您所见,空语句不仅合法,它还是短 C 语法的基础之一。

【讨论】:

  • 不幸的是,这也是非常糟糕的代码,应该有{},所以我不相信这是一个很好的例子。
  • 这不是例子,这是来自K&R的引文。
  • 如果我错了,请纠正我,但您的回答是“允许使用空语句,部分原因是 K&R 编写了使用它们的废话代码,本可以而且应该以另一种方式编写”。是这样吗?我只是不明白在这里引用while (...); 是一个答案。
  • 如果没有空语句,这段代码是不可能的。但这是可能的,并且它被 C 的作者推广为正确的 C 风格的一个例子。
  • “不可能”?上级while (*src++ = *dst++) {}怎么了? (我不在乎 C 的作者在几十年前是否认为这是“正确的 C 风格”;它是次等的,这是当今的普遍观念)
【解决方案3】:

在标准 §6/1§6.2/1(修订版 N3376)中有规定:

声明:

...

attribute-specifier-seq_opt 表达式语句

...

表达式语句:

表达式选择;

因此,一个语句可以是一个带有冒号的表达式语句,也可以是一个可选的表达式和一个属性说明符序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    相关资源
    最近更新 更多