Is C++ "declaration and initialization" statement, an expression?
Asked Answered
C

1

6

The language standard says:

[ Note: Clause 5 defines the syntax, order of evaluation, and meaning of expressions.58 An expression is a sequence of operators and operands that specifies a computation. An expression can result in a value and can cause side effects. — end note ]

E.g. I've code below:

int i=1;
A obj;

So, do both statements above, count as "expression"?

Some people on stackoverflow says "int i=1;" is not an expression. This is quite odd to me.

(1) An initialization is a kind of "computation", right? So it should be considered as "expression"?

(2) A obj; //invokes a ctor. A ctor is kind of computation, so it should be considered as "expression"?

Crisscross answered 4/7, 2016 at 2:23 Comment(5)
Possible duplicate of what's an expression and expression statement in c++?Foreside
A simple rule of thumb is that expressions don't have semi-colons. Adding a semi-colon turns them into statements. Also, an expression is something you can wrap with parentheses and use inside another expression. You can't write x = (int i=1;).Capps
Check the grammar, I've extracted it here: github.com/o11c/chintzy/blob/master-py/chintzy/_std/…Plasmo
@KeithThompson: 42 is a literal, which is a primary-expression. I don't know why you think it isn't. The note is non-normative, and does not define expressions.Like
@MSalters: You're right. I didn't notice that the note is non-normative. (The C standard has similar wording, and it's the normative definition of "expression".) I'll delete my earlier comment.Tomtom
P
6

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.

Penutian answered 4/7, 2016 at 3:13 Comment(5)
A declaration isn't an expression; some "full-expressions" are not expressions. The standard should use "full-expression" every time that it means full-expressionRiggle
Actually, A(i); is a declaration.Lolly
@VaughnCato My bad, will fix.Penutian
@VaughnCato Can you confirm that A(i); is a declaration? I've hunted around and I haven't been able to confirm. Specifically, my current understanding is that a declaration must introduce a name into the scope, which doesn't seem to be the case for A(i);.Shurlocke
@DanNissenbaum: A(i); is the same as A i; Example: godbolt.org/g/kz34FiLolly

© 2022 - 2024 — McMap. All rights reserved.