C++ primary expressions - Is it primary expression or not?
Asked Answered
P

2

11
  1. Why are they called "primary"? In the order of evaluence they are the first?

  2. C++03 standard defines the expression in chapter 5 (Note 1):

    An expression is a sequence of operators and operands that specifies a computation.

    Then the 5.1 "Primary expressions" defines the list of primary expressions:

    (1) primary-expression:

    literal
    
    this
    
    ( expression )
    
    id-expression
    

    My main question is in connection the third point:

    ( expression )
    

    So, according to the standard, every expression with brackets are primary expressions and they are calculated firstly. It looks logical, and gives an exact explanation of the behavior of brackets in C++ expressions (precedence).

    So this means that for example

    (variable + 10)
    

    is a primary expression.

    var = (variable + 10) * 3
    

    and according to my theory, it looks logic, BUT from other sources I know

    (variable + 10)
    

    is NOT a primary expression, but WHY? I don't understand, however the standard defines the (expression) as a primary expression.

Please, help me because I can't. Thank you very much, and sorry for my bad English. Hi.

Pyrogallate answered 23/6, 2013 at 9:49 Comment(5)
What are those "other sources" that say (variable + 10) is not a primary expression? And "primary expression" doesn't neccesarily mean it gets evaluated first.Glyptograph
Firstly I asked my question on another forum, there. It's not evaluted first? Then why are they called primary? Thank you for your help.Pyrogallate
I don't have an authorative answer as to why they're called primary. To my understanding, it's because they are some sort of building blocks for larger expressions. About order of evaluation, consider: int x = (1+5) - ++i; ++i might as well be evaluated first, even though it's a unary expression, not primary. And whoever said (variable + 10) is not a primary expression is plain wrong.Glyptograph
I understand. And the (variable + 10) is a primary expression or not?Pyrogallate
I read the following in a tutorial: "Primary expressions are not require further computing." This is not true, right?Pyrogallate
S
12

C++ expressions can be complex, which is to say they can be made up of nested expressions, combined through the use of operators, and those nested expressions may in turn be complex.

If you decompose a complex expression into ever smaller units, at some point you'll be left with units that are atomic in the sense that they cannot be decomposed further. Those are primary expressions; they include identifiers, literals, the keyword this, and lambda expressions.

However, it is true that there is one non-atomic construct that the C++ Standard defines as primary: Expressions enclosed in round brackets (aka parentheses). So the (variable + 10) example you give is a primary expression (and so are the sub-expressions variable (which is an identifier), and 10 (which is a literal).

I believe the Standard lists them as primary expressions because they play the some role as truly atomic expressions when it comes to the order of evaluation: Anything within the brackets must be evaluated before the value of the backeted expressions can enter into evaluations with other expressions: In (5+10)*a, the value of 5+10 must be evaluated before it can enter into the evaluation of *a. [Note that this does not mean 5+10 is evaluated before the expression a is evaluated. It only means that 5+10 must be evaluated before the multiplication itself can be evaluated.]

So, bracketed sub-expressions, in this sense, act as if they were atomic.

And I guess this is why the Standard doesn't use the term "atomic expressions" for this concept. They act as if they were atomic, but at least the bracketed variety is not actually atomic. "Primary" seems, to me, to be a good choice of words.

Schenck answered 23/6, 2013 at 10:13 Comment(4)
Thank you very much for your answer. The only thing that is not clear: "Clause 5 defines the syntax, order of evaluation, and meaning of expressions" (standard) Firstly the primary expressions (5.1), then postfix operators (5.2) etc... Primary expressions evaluted firstly or not as how jrok said?Pyrogallate
@Pyrogallate The Standard defines them first because they are the innermost part of complex expressions, and they take precedence in the evaluation order (but only in the sense explained in my answer). The order in which the expression types are described in the Standard corresponds largely to the precedence they take: E.g., in (a + b) * ++c, the bracket is evaluated before the multiplication, and so is prefix operator ++. (But the Standard does not say whether the bracket (a + b) is evaluated before ++c; these two are part of distinct sub-expressions.Schenck
Thank you. So please let me to test do I understood it well: (a + b) * ++c This is a complex expression, and the (a + b) is primary. The standard don't define that (so it's implementation-defined) the (a + b) or the ++c will be computed first, but the standard defines that: after the two sub-expression computed, then the multiplication is computed. By definition, the (a + b) is primary, because it behave as a primary expression, it need further computing and stands by a and b sub-expressions (and of course + operator). Is this okey?Pyrogallate
@Pyrogallate Yes, that's correct. In particular, your statements about the order of evaluation are correct, and it is correct that (a + b) is a primary expression. (Of course, a, b and c are also primary expressions, because they are identifiers. But ++c is not primary; it is a "unary expression".)Schenck
H
1

The term primary-expression is an element of the language grammar. They could equally have been called foobar-expression , it's just a name that doesn't have any deeper meaning.

A primary-expression is not necessarily atomic, evaluated first, top-level, more important than other expressions , or anything like that . And all expressions are "building blocks" because any expression can be added to to form a larger expression.

The definition was already given in the question so I won't repeat it here.

(variable + 10) is a primary-expression, your "other sources" are wrong. Here is another example of primary-expression:

([]{
int n, t1 = 0, t2 = 1, nextTerm = 0;

cout << "Enter the number of terms: ";
cin >> n;

cout << "Fibonacci Series: ";

for (int i = 1; i <= n; ++i)
{
    // Prints the first two terms.
    if(i == 1)
    {
        cout << " " << t1;
        continue;
    }
    if(i == 2)
    {
        cout << t2 << " ";
        continue;
    }
    nextTerm = t1 + t2;
    t1 = t2;
    t2 = nextTerm;
    
    cout << nextTerm << " ";
}
return 0;  
}())

(this calls a lambda function and parenthesizes the result; code borrowed from : here).


Also, the question flirts with a common misconception about precedence and order of evaluation. The standard doesn't mention "precedence" at all. A precedence table is a way of presenting the rules of the the language grammar in a way that is easier to read.

It refers to the way that operands are grouped with operators, not the order in which subexpressions are executed. In the case of f() + ([]{int n, t1 = 0, t2 = 1, nextTerm = 0; cout << "Enter the number of terms: ";.... etc. etc. , the f() may or may not be called before the lambda is called. The parentheses around the lambda do not cause it to be evaluated first.

Hectorhecuba answered 30/7, 2020 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.