2

我正在学习 C++,不小心写了

string s = "Some String";;;;

无论有多少分号,编译器都不会抱怨。这几乎适用于所有语句,除了编译器所说的 if 块内

 ‘else’ without a previous ‘if’ 

我正在使用 GCC 4.7

4

3 回答 3

12

以下是C++ 语法的一部分:

expressionopt ;

其中下标opt表示这expression是可选的。

另一方面,该if语句的语法是:

if ( condition ) statement

并且不是有效的.expressionopt ;condition

于 2013-10-24T16:29:04.700 回答
6

C++ 语法(如之前的 C)允许空语句。在某些情况下,它们实际上甚至很有用。一种情况是循环将所有动作放入条件中,因此循环体不需要做任何事情。一个典型的例子是 Cstrcpy函数的实现:

while (*d++ = *s++)
    ;

当您这样做时,您通常确实希望像这样将分号单独放在一行上,而不是放在同一行的末尾,例如while (*d++ = *s++);. 编译器并不关心差异,但将其放在单独的行上有助于让读者放心,循环仅控制单个空语句是故意的。有些人也喜欢添加评论,例如:

while (*d++ = *s++)
   /* intentional null statement */ ;

就个人而言,我认为单独一行上的分号就足够了,但这就是生活。

于 2013-10-24T16:50:08.397 回答
6

添加其他答案中未提及的内容:

在一般情况下,这个序列;;;代表什么取决于使用它的上下文。

如果你声明

string s = "Some String";;;;

本地范围内(即在函数内),那么您上面所拥有的是变量的声明语句s,而过多;的 s 将代表空语句,正如其他答案中已经说明的那样。这在 C++ 中一直是合法的。

但如果你这样做

string s = "Some String";;;;

命名空间范围内,多余;的 s 不再代表空语句。命名空间范围内不允许使用语句。上面的内容是变量的声明(不是声明语句,而仅仅是声明s,然后是一系列空声明。在 C++11 之前的 C++ 语言中,空声明曾经是非法的,这意味着在 C++98 和 C++03 中,如果在命名空间范围内使用上述声明确实会产生语法错误。

如果在范围内使用上述声明,那么由于其他原因,它在 C++98 和 C++03 中立即是非法的:它包含一个初始化程序,这在 C++11 之前的语言版本中是不允许的。在 C++11 中,在类范围声明中包含初始化程序是合法的。在这种情况下, 的序列;;;也是空声明序列,而不是空语句序列。

于 2013-10-24T17:47:40.660 回答