QnA
QnA

Reputation: 1103

expected primary-expression before ‘...’, c++ compile error

There are quite a few posts on SO with similar titles, but they seem to be triggered by various syntactic errors and I didn't see a consistent pattern yet..

using namespace std;

class A
{
public:
    A(int a_) : a(a_) {}
    int a;
};

int main()
{
    A x{3};
    A y{0};

    if ((y=x).a)
        cout << y.a << endl;
        
    int i = 1;
    if (int j = i)
        cout << j << endl;
    
    if ((A z = x).a) // error: expected primary-expression before ‘z’
        cout << z.a << endl;

    (int m = 1); // error: expected primary-expression before ‘int’
}

Am I wrong to assume A z = x is an assignment expression, which should have the same value as z?

Upvotes: 0

Views: 4072

Answers (2)

JaMiT
JaMiT

Reputation: 16841

Am I wrong to assume A z = x is an assignment expression

Yes, you are wrong. There is no assignment going on here. The = in this statement represents initialization, not assignment. The statement A z = x; defines the variable z, where z is constructed from x. The copy constructor is used here, not copy assignment. It is a declaration statement, not an expression statement.

Your confusion is reasonably common, and it is made worse by the fact that the condition in an if statement can be a declaration of a single non-array variable with a brace-or-equals initializer. Syntactically, a declaration with an "equals" initializer can look a lot like an assignment. A big difference, as you discovered, is that you cannot treat the declaration as a sub-expression. The condition is either a declaration or an expression, not a mix of both.

The good news is that C++-17 added an optional init-statement to the if statement syntax. So what you appear to want would be achieved by the following.

    if ( A z = x; z.a )  // Semicolon separates init-statement from condition
        cout << z.a << endl;
    // At the end of the `if` statement, `z` goes out of scope.

Upvotes: 5

catnip
catnip

Reputation: 25388

You can't declare a variable in an if statement in that fashion. The declaration has to be of the form:

if (X x = y) ... (or if (auto x = y) ...)

However, you can still achieve what you are trying to do if you provide a suitable conversion operator in class A, like this:

#include <iostream>

using namespace std;

class A
{
public:
    A(int a_) : a(a_) {}
    int a;
    operator bool () { return a != 0; }
};

int main()
{
    A x{3};
    const A &y = x;
    if (y.a)
        cout << y.a << endl;
    if (A z = x)
        cout << z.a << endl;
}

Live demo

Upvotes: 3

Related Questions