skgbanga skgbanga - 24 days ago 8
C++ Question

Putting extra round brackets - code fails to compile

So, I have a function that returns a boolean

bool func_true()
{
// do some stuff
return true;
}


Now actual code call this like this

if (auto err = func_true())
{
// some stuff
std::cout << std::boolalpha << err << '\n';
}


All good till this point. If I put an extra round bracket around my call, compilation fails:

if ((auto err = func_true())) // doesn't compile!
{
std::cout << std::boolalpha << err << '\n';
}


GCC Error:

error: expected primary-expression before 'auto'
if ((auto err = func_true()))
^~~~


http://coliru.stacked-crooked.com/a/812424bfdb66eec3

Is this a gcc bug, or I am doing something stupidly wrong?

Answer

The syntax (according the latest C++ standard, ISO/IEC 14882:2014) of an if statement is as follows:

if ( condition ) statement [else statement]

The syntax for a a condition is as follows:

expression

[ attribute-specifier-seq ] decl-specifier-seq declarator = initializer-clause

[ attribute-specifier-seq ] decl-specifier-seq declarator braced-init-list

Now the code auto err = func_true() matches the second form on the condition, specifically, auto matches decl-specifier-seq, err matches declarator and func_true() matches initializer-clause

But the code (auto err = func_true()) can't match the second or third forms of condition as ( cannot start an attribute-specifier-seq nor a decl-specifier-seq, however it can start an expression

To which the syntax is:

[ expression ,] assignment-expression

Now if you follow the syntax definitions, you will find that auto cannot start an expression (an identifier can, but auto is a keyword, so not an identifier)

To put it simply, GCC's behaviour is correct, it is a syntax error.

Comments