在C ++中,每个"语句"还有表达吗?

时间:2016-06-23 10:40:52

标签: c++ expression language-lawyer difference

我可以说在C ++中,每个语句(没有分号)也是一个表达式吗?

另外,所有表达式,添加分号,都可以成为一个声明? 感谢。

3 个答案:

答案 0 :(得分:7)

表达式后跟分号确实是 expression_statement ,这是一种陈述。

但反过来不一定是真的:例如考虑 jump_statement

goto foo;

此处goto foo 不是表达式。

答案 1 :(得分:7)

不,C ++语句并不总是表达式。例如,for循环不是表达式(类型void)。因此即使使用comma operator,以下内容也是错误的:

 /// wrong code, syntactically incorrect in C++
 for (int i=0; i<5; i++) {std::cout<<i<<std::endl;}
 , // this is a comma operator
 x+3

(您可以用+之类的任何其他运算符替换逗号运算符,但它仍然是错误的)

但当然,表达式(包括赋值和调用)可以用作语句。

请注意,GCC提供语言扩展statement exprsClang/LLVM接受此扩展名);这是一个简单的例子(语句表达式的值由2*x给出):

#include <iostream>

void f (int x) {
   // notice the statement-expr starting inside ({ ... })
   // the last expression inside the braces gives the value
   int y = ({std::cout << "x=" << x << std::endl; 2*x;})+1;
   std::cout << "y=" << y << std::endl;
}

如果C ++ 11编译器不接受该扩展,您可以使用lambda-expression创建一个闭包并立即应用它以获得相同的效果:

void f (int x) {
  int y = ([=](){std::cout << "x=" << x << std::endl; return 2*x;})() + 1;
  std::cout << "y=" << y << std::endl;
}

希望优化编译器不会打扰创建中间闭包并生成与GCC可以给出的代码(使用g++ -O2)与expr变量语句

相同的代码

某些语言,特别是Ocaml,Scheme,Haskell,没有语句或说明。他们只有表达式(其中一些可能有一些副作用)。

答案 2 :(得分:1)

语句可以由任意数量的事物(包括表达式)组成,但语句本身不是表达式。

看看§A.5。