+ 1
[CLOSED] Why am I getting a type narrowing warning when I was initializing a std::bitset object using uniform initialization?
Hey SoloLearners! ✋ I'm getting a type narrowing warning when I initialize a bitset object using an `int` value in uniform initialization. Warning doesn't come when I initialize by regular initialization. But why is that different? I thought uniform initialization is the new "norm", I'm confused here ... Oh and here's the snippet ... https://code.sololearn.com/c4waLLlYcpAu/?ref=app T.I.A guys and ladies 🙏
12 odpowiedzi
+ 2
It's in general to all type of list initialization
https://en.cppreference.com/w/cpp/language/list_initialization
+ 3
From Cpp Reference:
http://www.cplusplus.com/reference/bitset/bitset/bitset/
We know that there is no bitset(int) but bitset(unsigned long long). Thus implicit conversion is required and -Wnarrowing is raised.
+ 2
Мг. Кнап🌠
Thank you so much! 🙏
+ 1
You are using curved brackets { } in line 11.
In other, normal brackets as per constructor..
+ 1
Ipang
The compiler checks the available constructors for std::bitset and sees that it has to convert from int to unsigned long long, chances are int could be potentially be negative, so we have a narrowing conversion warning.
So if we just declare
unsigned int decimal_integer;
Then compiler is assured that there won't be a negative integer
+ 1
CarrieForle
Thank you for response 🙏
So in line 12 the constructor (2nd overload - from above link) implicitly casts the `int` into an `unsigned long`?
I had tried to cast `int` to `size_t`, `unsigned long` and `unsigned long long`, and saw that it worked. My doubt is, why the uniform initializer isn't following the same path, such that I needed to do the casting manually?
+ 1
Jayakrishna🇮🇳
Curly brackets is C++11 feature, known as uniform initialization, this is not a problem bro 👌
+ 1
Мг. Кнап🌠
Thank you for response 🙏
Yes bro, I see that also from CarrieForle's answer. But my doubt is, why it only gives warning when I'm using uniform initialization. Why uniform initialization isn't working similarly as normal initialization (like at line 12). I don't get why it is working differently bro ...
+ 1
Ipang
From cppreference
If the initializer clause is an expression, implicit conversions are allowed as per copy-initialization, except, for list-initialization form, narrowing conversions are prohibited (since C++11).
EDIT:--
Further for List initialisation
list-initialization limits the allowed implicit conversions by prohibiting the following:
• conversion from a floating-point type to an integer type.
• conversion from a long double to double or to float and conversion from double to float, except where the source is a constant expression and overflow does not occur.
• conversion from an integer type to a floating-point type, except where the source is a constant expression whose value can be stored exactly in the target type.
• conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type
+ 1
Мг. Кнап🌠
Please share the link to the reference, I can't find that statement in the bitset constructors page in cppreference. Maybe I skipped it?
+ 1
Jayakrishna🇮🇳
Check the link in Mr Khan bro latest reply. That answered my doubt clearly.
0
Ipang iam not good at c++ but I tried code by changing {} to () it worked. So default constructor also using () of unsigned long long int.
std::bitset<32> binary_1 (-5); this is working fine.
std::bitset<32> binary_1 {-5} ; this is error.
So I think later it is explicit convertion so warning.. explicitly singed int to unsigned..
The former is implicit convertion, what I'm understood..
I replayed, that I thought you can find the difference if that was the is real cause.. Let me know difference..