Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

braced-init-list and unsigned types

gcc 8 and clang 7 do not accept the following code, which should default-construct a temporary of type unsigned int:

unsigned int ui = unsigned int{};

clang 7 reports an error such as

<source>:6:22: error: expected primary-expression before 'unsigned'

Visual C++ 2015 and 2017 accept this.

Obviously, this works with a type such as int, or any default-constructible class type.

Is this correct C++14 code (and in that case a bug of clang and gcc)? If not, why not? Which types other than unsigned types would suffer from the same restriction?

like image 560
Simon Avatar asked Nov 16 '18 10:11

Simon


People also ask

What is a braced init list?

a braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an std::initializer_list parameter.

What is braced init list in C++?

initializer_list constructorsThe initializer_list Class represents a list of objects of a specified type that can be used in a constructor, and in other contexts. You can construct an initializer_list by using brace initialization: C++ Copy. initializer_list<int> int_list{5, 6, 7}; Important.


2 Answers

new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.

A single-word type name followed by a braced-init-list is a prvalue of the specified type designating a temporary (until C++17) whose result object is (since C++17) direct-list-initialized with the specified braced-init-list.

Note that unsigned int is not a single-word type name, while int is. So int {} works fine.

This is same for functional cast expression,

The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name: unsigned int(expression) or int*(expression) are not valid),

As a workaround, you can apply type alias, e.g.

using type = unsigned int;
type ui = type{};
like image 189
songyuanyao Avatar answered Sep 27 '22 20:09

songyuanyao


"Int" is optional in "unsigned int".

Try simply:

unsigned ui = unsigned{};

It works.

Edit: I found this answer: Standard behavior for direct initialization of unsigned short

It's just because only single-word type name could be used in functional cast expression, while unsigned short is not a single-word type name; short is.

like image 22
artona Avatar answered Sep 27 '22 18:09

artona