What's an Expression and Expression Statement in C++

what's an expression and expression statement in c++?

An expression is "a sequence of operators and operands that specifies a computation" (that's the definition given in the C++ standard). Examples are 42, 2 + 2, "hello, world", and func("argument"). Assignments are expressions in C++; so are function calls.

I don't see a definition for the term "statement", but basically it's a chunk of code that performs some action. Examples are compound statements (consisting of zero or more other statements included in { ... }), if statements, goto statements, return statements, and expression statements. (In C++, but not in C, declarations are classified as statements.)

The terms statement and expression are defined very precisely by the language grammar.

An expression statement is a particular kind of statement. It consists of an optional expression followed by a semicolon. The expression is evaluated and any result is discarded. Usually this is used when the statement has side effects (otherwise there's not much point), but you can have a expression statement where the expression has no side effects. Examples are:

x = 42; // the expression happens to be an assignment

func("argument");

42; // no side effects, allowed but not useful

; // a null statement

The null statement is a special case. (I'm not sure why it's treated that way; in my opinion it would make more sense for it to be a disinct kind of statement. But that's the way the standard defines it.)

Note that

return 42;

is a statement, but it's not an expression statement. It contains an expression, but the expression (plus the ;) doesn't make up the entire statement.

Expression Versus Statement

Expression: Something which evaluates to a value. Example: 1+2/x
Statement: A line of code which does something. Example: GOTO 100

In the earliest general-purpose programming languages, like FORTRAN, the distinction was crystal-clear. In FORTRAN, a statement was one unit of execution, a thing that you did. The only reason it wasn't called a "line" was because sometimes it spanned multiple lines. An expression on its own couldn't do anything... you had to assign it to a variable.

1 + 2 / X

is an error in FORTRAN, because it doesn't do anything. You had to do something with that expression:

X = 1 + 2 / X

FORTRAN didn't have a grammar as we know it today—that idea was invented, along with Backus-Naur Form (BNF), as part of the definition of Algol-60. At that point the semantic distinction ("have a value" versus "do something") was enshrined in syntax: one kind of phrase was an expression, and another was a statement, and the parser could tell them apart.

Designers of later languages blurred the distinction: they allowed syntactic expressions to do things, and they allowed syntactic statements that had values.
The earliest popular language example that still survives is C. The designers of C realized that no harm was done if you were allowed to evaluate an expression and throw away the result. In C, every syntactic expression can be a made into a statement just by tacking a semicolon along the end:

1 + 2 / x;

is a totally legit statement even though absolutely nothing will happen. Similarly, in C, an expression can have side-effects—it can change something.

1 + 2 / callfunc(12);

because callfunc might just do something useful.

Once you allow any expression to be a statement, you might as well allow the assignment operator (=) inside expressions. That's why C lets you do things like

callfunc(x = 2);

This evaluates the expression x = 2 (assigning the value of 2 to x) and then passes that (the 2) to the function callfunc.

This blurring of expressions and statements occurs in all the C-derivatives (C, C++, C#, and Java), which still have some statements (like while) but which allow almost any expression to be used as a statement (in C# only assignment, call, increment, and decrement expressions may be used as statements; see Scott Wisniewski's answer).

Having two "syntactic categories" (which is the technical name for the sort of thing statements and expressions are) can lead to duplication of effort. For example, C has two forms of conditional, the statement form

if (E) S1; else S2;

and the expression form

E ? E1 : E2

And sometimes people want duplication that isn't there: in standard C, for example, only a statement can declare a new local variable—but this ability is useful enough that the
GNU C compiler provides a GNU extension that enables an expression to declare a local variable as well.

Designers of other languages didn't like this kind of duplication, and they saw early on that if expressions can have side effects as well as values, then the syntactic distinction between statements and expressions is not all that useful—so they got rid of it. Haskell, Icon, Lisp, and ML are all languages that don't have syntactic statements—they only have expressions. Even the class structured looping and conditional forms are considered expressions, and they have values—but not very interesting ones.

What is the difference between an expression and a statement in Python?

Expressions only contain identifiers, literals and operators, where operators include arithmetic and boolean operators, the function call operator () the subscription operator [] and similar, and can be reduced to some kind of "value", which can be any Python object. Examples:

3 + 5
map(lambda x: x*x, range(10))
[a.x for a in some_iterable]
yield 7

Statements (see 1, 2), on the other hand, are everything that can make up a line (or several lines) of Python code. Note that expressions are statements as well. Examples:

# all the above expressions
print 42
if x: do_y()
return
a = 7

Explaining the difference between a statement and an expression in c++

Which one is correct?

Both: it is an expression statement. C and C++ let you put an expression into a body of code, add a semicolon, and make it a statement.

Here are some more examples:

x++;       // post-increment produces a value which you could use
a = 5; // Assignment produces a value
max(a, b); // Call of a non-void function is an expression
2 + x; // This calculation has no side effects, but it is allowed

Note that this is true in the specific case of C and C++, but may not be true in case of other languages. For example, the last expression statement from the list above would be considered invalid in Java or C#.

I want to understand in detail distinct between expression and statement in C++. Pls pick concrete example to explain that

Concretely, What do "side effect" and "result" mean here?

Expression has no side-effects, when removing it from source does not change program semantics.

int main(void) {
int x = 1, y = 2, z = 0;
// x+y expression calculates sum and ignores resulting answer
// NO SIDE EFFECTS, can be removed
x+y;
// x+y expression calculates sum, but then 15 is assigned to z as a result
// SIDE EFFECT is that removing given expression breaks program syntax - can't be removed
z = (x+y, 15);
}

EDIT

BTW, keep in mind that not all expression statements has side-effects too. For example x=x; is technically equivalent to ; - an empty statement which is compiled into NOP at assembly level or skipped by GCC optimizer at all. So these kinds of expression statements has no side-effects and can be removed safely from a program. But it doesn't mean that you can remove each empty statement without changing program logic. For example as in this snippet :

for (i=0; i < 10; i++);
Here NOP is executed with each CPU cycle, so if you will remove it - program semantics will change radically.

What is a full expression in C?

He's taken this straight from the C standard, example C11 6.8:

A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer that is not part of a compound
literal; the expression in an expression statement; the controlling expression of a selection
statement (if or switch); the controlling expression of a while or do statement; each
of the (optional) expressions of a for statement; the (optional) expression in a return
statement. There is a sequence point between the evaluation of a full expression and the
evaluation of the next full expression to be evaluated.

Some examples would be:

if(x)

for(x; y; z)

return x;

where x y and z are full expressions.

Full expression is a language grammar term and not really something a C programmer needs to know about. It is only relevant to "language lawyers" and those making compilers or static analysers. The C standard speaks of statements, blocks and full expressions.

What the programmer might need to know is the last sentences of the above cited text, which means that after a full expression, all side effects of that expression are carried out. So if I write code such as if(i++) printf("%d", i); then I know that the i++ has been carried out before the printf line.

It may however be quite useful to know these dry grammar terms when reading compiler errors. Such as the infamous "statement missing", that most likely means, in plain English, that you've forgotten a semicolon.

Is the return statement considered to be an expression statement in C?

A return statement and an expression statement are two different things.

Section 6.8.3 of the C standard gives the syntax for an expression statement:

expression-statement:

  • expressionopt;

While section 6.8.6 gives the syntax of a return statement:

jump-statement:

  • goto identifier;
  • continue;
  • break;
  • return expressionopt;

Also, this is not an expression statement (in fact not a statement at all):

int x = 7;

But a declaration.

Is C++ declaration and initialization statement, an expression?

That non-normative note in the standard is intended to motivate the concept of an expression, but is not the actual definition. The definition of expression is given in the language grammar which is given in the remainder of clause 5. Expressions are built out of certain terminals such as literals, names of variables, and names of functions, which are combined using operators such as arithmetic and relational operators.

Declarations and expressions are distinct syntactic entities, so a declaration found inside a C++ program is never an expression, and vice versa. The difference is fairly easy to see at a glance: if it declares something, it's a declaration.

1;          // expression statement
int i = 1; // declaration statement that declares `i`
A(i, 42); // expression statement that creates an A object
A a(i); // declaration statement that declares an A object (named a)

A declaration can evaluate expressions but a declaration is not an expression. You rightly point out that the declaration of an object of class type can cause a constructor call. Still it is syntactically a declaration and not an expression.

However, there is another sense in which a declaration is an expression. Namely, rules about the sequencing of evaluations within expressions also apply to declarations. For example, there is a rule that the side effect of a postfix increment on an int takes place at some point before the end of the full-expression.

f(i++) + g();  // i may be incremented before or after g() is called...
h(); // but definitely before h() is called.

For the purposes of such rules, the declaration and initialization of a single variable is considered to also be a full-expression. In the case of a variable of class type, the constructor call is part of that expression.

int i = 1;                      // this declaration evaluates a full-expression
// whose effect is to initialize `i` to 1
int j = f(i++) + g(), k = h(); // two separate full-expressions;
// i is incremented before h() is called

When reading the standard, you need to consider the context in order to figure out what sense of "expression" is meant.



Related Topics



Leave a reply



Submit