cast uint16 to int32

Mar 4, 2013 at 7:19pm
by casting a unsigned short to a singed long, is there any chance to generate a negative value?

Thanks

Mar 4, 2013 at 8:39pm
Yes if sizeof(unsigned short) == sizeof(signed long).
Last edited on Mar 4, 2013 at 8:39pm
Mar 4, 2013 at 8:45pm
Your question does not match your topic title.
Mar 4, 2013 at 9:20pm
first, usigned short is uint16 and signed long is int32. size of uint16=2 while int32=4, which means No, right?

LB, I am not sure what you are referring to. Am I missing anything?

How about

uint64_t t = ...
int32_t i = static_cast<int32_t> (t);

is there any chance that i could be negative for this? I actually wrote a small program to prove it in windows on uint16 case, seems never the case. did not try it in gcc though.

thanks for the help
Mar 4, 2013 at 9:35pm
2^sizeof(t*8)-1 is the max range of a type.

1
2
uint64_t t = ...
int32_t i = static_cast<int32_t> (t);


Would result to negative value, or at least not the desired value if 2^sizeof(i*8)-1< t;

This i am not completely sure of though.
But if the resulting value is out of range for the type of i, at least in regular variables, what is left out of the range goes + from the lowest value of i.
So it probably applies here too.
Last edited on Mar 4, 2013 at 9:41pm
Mar 4, 2013 at 10:39pm
chrisben wrote:
LB, I am not sure what you are referring to. Am I missing anything?
I meant that shorts and longs aren't always 2 and 4 bytes respectively.
chrisben wrote:
1
2
uint64_t t = ...
int32_t i = static_cast<int32_t> (t);
I think you meant this the other way around.

@IndieExe "2^sizeof(t*8)-1" is not a range.
Last edited on Mar 4, 2013 at 10:40pm
Mar 26, 2013 at 10:06am
@IndieExe "2^sizeof(t*8)-1" is not a range.

Anything measured is a range from a to b, is it not?
Mar 26, 2013 at 2:13pm
1
2
> uint64_t t = ...
> int32_t i = static_cast<int32_t> (t);


> is there any chance that i could be negative for this?

No.

An explicit cast is not required; std::int32_t i = t ; would suffice.

C++11: To be certain, use {} initialization; it does not allow narrowing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <cstdint>
#include <limits>

int main()
{
    std::cout << std::numeric_limits< std::uint16_t >::max() << '\n'
               << std::numeric_limits< std::int32_t >::max() << '\n' ;

     // C++11
    std::uint16_t t = std::numeric_limits< std::uint16_t >::max() ;
    std::int32_t i = {t} ; // fine

    // std::int16_t u = {t} ; // *** error: narrowing conversion

    std::cout << t << ' ' << i << '\n' ;
}
Mar 26, 2013 at 4:06pm
@JLBorges: an implicit narrowing cast from unsigned 64 bit to signed 32 bit is allowed!?
http://ideone.com/f9uTdY o_o
Why? Why in the world is this allowed?
Mar 26, 2013 at 9:45pm
@LB It's not allowed. GCC generates a warning but it looks like ideone has disabled that warning.
warning: narrowing conversion of ‘huge’ from ‘uint64_t {aka long unsigned int}’ to ‘int32_t {aka int}’ inside { } [-Wnarrowing]
Mar 26, 2013 at 11:02pm
What I mean is, why does it only generate a warning and not en error? I consider 'not allowed' to mean 'generates an error', whereas this just generates a warning so it is more deprecated than not allowed.
Mar 27, 2013 at 2:14am
> an implicit narrowing cast from unsigned 64 bit to signed 32 bit is allowed!?

No. (within {} ).

> why does it only generate a warning and not en error?

It is an error; as usual with g++, in the absence of -pedantic-errors we don't get conformance.
http://liveworkspace.org/code/3lQsMh$0

Last edited on Mar 27, 2013 at 2:15am
Mar 27, 2013 at 2:42am
Ah, thanks - I just found some problems in some of my older code :)
Topic archived. No new replies allowed.