"if" C 和 C++ 之间的语句语法差异


if (1) int a = 2;

这行代码是有效的c++代码(它至少可以编译),但无效的C代码(不能编译)。我知道语言有差异但这是意想不到的。

我一直以为语法是

if (expr) statement

,但这将使它在两者中都有效。

我的问题是:

  1. 为什么不能在C中编译?
  2. 为什么存在这种差异?

这是C和c++之间微妙而重要的区别。在c++中,任何语句都可以是声明语句。在C语言中,没有所谓的声明语句;相反,可以在任何复合语句中出现声明而不是语句

来自C语法(C17规范):

复合语句:"{";block-item-list<子>选择"}">
block-item-list:block-item|block-item-listblock-item
block-item:声明|声明

来自c++语法(c++ 14规范):

复合语句:"{";statement-seq<子>选择"}">
statement-seq:声明|statement-seq声明
声明:…|声明-语句|…

不清楚为什么存在这种差异,这只是语言进化的方式。c++的语法可以一直追溯到(至少)c++ 85。C语法是在C89和C99之间的某个时候引入的(在C89中,声明必须在块的开头)


在最初的c++ 85和89版本中,在声明语句中定义的变量的作用域是"直到封闭的块(")结束为止"。因此,像这样的if中的声明不会立即超出作用域(就像在最近的版本中那样),而是在同一块作用域中跟随if的语句的作用域中。当条件为false时,这可能导致访问未初始化数据的问题。更糟糕的是,如果var有一个重要的析构函数,它将在作用域结束时被调用,即使它从未被初始化!我怀疑试图避免这类问题是导致C采用不同语法的原因。

Chris的回答(和其他人的回答)显示了语法的不同。

我想指出if (1) int a = 2;在C中没有意义,但在c++中有意义。因为我们没有一个块,只有一个语句/声明,所以不可能进一步使用声明的变量(它会立即超出作用域)。在C语言中,允许这样做是没有意义的,但在c++中,构造函数和析构函数可能有副作用,因此定义和初始化一个立即超出作用域的变量可能是有用的,并且必须被允许。

这是因为C和c++对语句的定义不同。

在C语言中,声明不被归类为语句。C复合语句由开始的{块项s选项列表和结束的}组成,其中块项要么是声明,要么是语句。(这在C99中改变了,当C增加了在块中混合声明和语句的能力。)

在c++中,声明被归类为语句(但仅当它位于复合语句内时)。这允许对复合语句进行更简单的定义:它是一个{,后跟一个可选的语句s列表,后跟一个}

差异没有太多的实际效果;总有办法绕过它。一个效果是,在c++中,紧跟在case标签后面的声明是合法的,但在C中,这是不合法的。

在C语言中,声明语句是不同的实体。

在c++中,称为块声明的声明子集是一种语句类型,特别是声明语句。这些包括简单的声明,如int a=2

相关内容

  • 没有找到相关文章

最新更新