Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is (multi-word type name){expression-list} legal?

Consider:

(long long){1};

It’s not a C-style cast expression per [expr.cast]/1:

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

cast-expression:

  • unary-expression
  • ( type-id ) cast-expression

{1} shouldn’t be a cast-expression.

It’s also not a functional-style cast expression per [expr.type.conv]/1:

A simple-type-specifier or typename-specifier followed by a parenthesized optional expression-list or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer. If the type is a placeholder for a deduced class type, it is replaced by the return type of the function selected by overload resolution for class template deduction for the remainder of this subclause. Otherwise, if the type contains a placeholder type, it is replaced by the type determined by placeholder type deduction ([dcl.type.auto.deduct]).

simple-type-specifier:

  • nested-name-specifier opt type-name
  • nested-name-specifier template simple-template-id
  • decltype-specifier
  • placeholder-type-specifier
  • nested-name-specifier opt template-name
  • char
  • char8_­t
  • char16_­t
  • char32_­t
  • wchar_­t
  • bool
  • short
  • int
  • long
  • signed
  • unsigned
  • float
  • double
  • void

(long long) shouldn’t be a simple-type-specifier.

It doesn’t seem legal, but it should be, why?

>Solution :

It is not valid syntax in ISO standard C++.

In C it is the syntax for a compound literal. Compilers by default often support that also in C++ mode as an extension. When enabling strict(er) standard conformance they should reject it or at least provide a warning (e.g. with -pedantic, -pedantic-errors)

Whether there are multiple words doesn’t matter by the way. (long){1} has the same problem. (/*..*/){/*..*/} can’t be syntax for an expression as can be seen from the standard quotes you gave.

Also, in C such a compound literal is an lvalue like string literals. That would be confusing in C++, where an analogues cast expression, i.e. T{1} with using T=long long;, produces a prvalue. The lifetime of the resulting object is also very different. Therefore supporting them in C++ would either have a different meaning as in C or mean a confusing difference between (T){e}and T{e}.

Here is a closed proposal from 2020-2022 to introduce compound literals in C++. As you can see from the voting results there wasn’t a consensus whether to add them at all or what behavior they should have.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading