Home > Software engineering >  Is `auto(expr)` treated as cast at the beginning of the expression statement?
Is `auto(expr)` treated as cast at the beginning of the expression statement?

Time:05-08

I have a simple code snippet shown below (https://godbolt.org/z/cPT3PhYdj):

int main() {
  int x = 1;
  auto(1); // why
  auto{1}; // why
  static_cast<void>(auto(x)); // ok
  auto{x}; // why
  auto(x); // why
}

Where both GCC and Clang emit an error showing:

// by GCC Trunk [-std=c  23]
<source>: In function 'int main()':
<source>:7:3: error: declaration of 'auto x' has no initializer
    7 |   auto(x); // why
      |   ^~~~
Compiler returned: 1

// by Clang Trunk [-std=c  2b]
<source>:3:8: error: expected unqualified-id
  auto(1); // why
       ^
<source>:3:8: error: expected ')'
<source>:3:7: note: to match this '('
  auto(1); // why
      ^
<source>:4:7: error: expected unqualified-id
  auto{1}; // why
      ^
<source>:6:7: error: expected unqualified-id
  auto{x}; // why
      ^
<source>:7:8: error: redefinition of 'x'
  auto(x); // why
       ^
<source>:2:7: note: previous definition is here
  int x = 1;
      ^
<source>:7:8: error: declaration of variable 'x' with deduced type 'auto' requires an initializer
  auto(x); // why
       ^
6 errors generated.
Compiler returned: 1

Are these expressions supposed to be parsed as explicit type decay conversion auto(expr) or auto{expr} in expression statements or parsed as a declaration?

If auto(identifier) is reinterpreted as auto identifier, then which priority comes first, the declaration or the auto(identifer) cast expression?

CodePudding user response:

From Explicit cast conversion:

auto ( expression )   (8)     (since C  23)

auto { expression }   (9)     (since C  23)

8,9) The auto specifier is replaced with the deduced type of the invented variable x declared with auto x(expression); (which is never interpreted as a function declaration) or auto x{expression}; respectively. The result is always a prvalue of an object type.

So your usage seems to be allowed(in accordance with ) by the above quoted statement.

Here is a working demo of your code. Note in the linked demo, only the usage auto(x) produces an error, all other cases work fine.


Also note that from PR105516:

auto(x); is interpreted as auto x;. Use auto(x); if you want that to be an expression.

CodePudding user response:

As far as I can tell the paper introducing this feature didn't make any further relevant changes except to allow auto as type specifier in a functional-style explicit cast.

So intuitively auto here should behave the same as any other type specifier would.

For example, replacing auto with int, it is expected that all of these cases work and are functional-style explicit casts, except

int(x); // auto(x);

This one could according to the grammar also be a declaration of a variable named x of type int (or placeholder type) with parentheses around the declarator and without initializer.

As usual, the grammar is disambiguated by preferring the interpretation as declaration (see [stmt.ambig]/1). At least, I don't think that it should be different for auto. A declaration with auto placeholder type requires an initializer, which is not present in this interpretation, but according to [stmt.ambig]/3 the disambiguation is supposed to be done very early and purely syntactic even if it ends up in an ill-formed declaration. I am not completely sure but I guess this should mean that auto(x); should still be disambiguated as a declaration.

I don't know why Clang gives errors for many of the other lines. I suppose the feature is either implemented only partially or these are implementation bugs (it is a very new feature in an unfinished standard revision).

  • Related