A-n-t-h-o-n-y
A-n-t-h-o-n-y

Reputation: 410

`auto` variable declaration with multi-word fundamental types causes error

Is it possible to declare a variable with the auto keyword and a type name that is made of two or more words?

And if not, why not?

For example

auto foo = unsigned int{0};

Give the following compiler output

Clang:

error: expected '(' for function-style cast or type construction

GCC:

error: expected primary-expression before 'unsigned'

Upvotes: 4

Views: 407

Answers (3)

Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29965

Whenever you want the compiler to group multiple things but it doesn't, you use parentheses to force it:

auto foo = (unsigned int)(0);

Note that as @cpplearnern points out, if you use curly braces instead, it counts as a compound literal and is not legal C++, though is legal C99:

auto foo = (unsigned int){0}; /* Not legal C++, though GCC and Clang support it. */

In any case, a better solution is to use integral literals:

auto foo = 0u;

Upvotes: 2

R Sahu
R Sahu

Reputation: 206567

For

auto foo = T{0};

to work, T has to be a simple-type-specifier.

From the C++11 Standard/5.2.3 Explicit type conversion (functional notation)/3

Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized ([dcl.init.list]) with the specified braced-init-list, and its value is that temporary object as a prvalue.

If you see the definition of simple-type-specifier, unsigned int is not one of them.

You can use any of the following:

auto foo = 0U;
auto foo = (unsigned int)0;
auto foo = static_cast<unsigned int>(0);

Upvotes: 6

Emil Vatai
Emil Vatai

Reputation: 2531

What you are looking for is probably here http://www.cplusplus.com/doc/tutorial/typecasting/ (section "Type casting").

And maybe this is even better: https://en.cppreference.com/w/cpp/language/explicit_cast Under this link, you are using syntax (5): new_type { expression-list(optional) }.

So if you have a space in your type name how will the compiler guess if unsigned int {0} is (unsigned int) {0} (what you meant probably), or is it (unsigend (int {0})) (which would be actually two conversions)... so you have to explicitly put the type name into parenthesis.

This would be important if you'd want to do long unsigned {x}, because then I'd result in

  • long if it is interpreted as long (unsigned {x})
  • unsigned long if it is interpreted as (long unsigned){x}

Upvotes: 1

Related Questions