473,396 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

static_cast<unsigned short)( -1 ) Well defined?

Is the following well defined?

size_t IntVal = 65537;
unsigned short Length;

if ( IntVal static_cast<unsigned short>( -1 ) )
{
std::cout << "Value too long to fit in a short" << std::endl;
}
else
{
std::cout << "Value fits" << std::endl;
Length = static_cast<unsigned short>( IntVal );
}

What I'm actually going to be using it for is to send a length short through
sockets, and I want to ensure that the length isn't greater than 65535.
Rather than the magic number, I was thinking that static_cast<unsigned
short>( -1 ) would be better. Is this well defined? Will it equal 65535 in
all cases where a short is a 2 byte integer?
Nov 21 '06 #1
10 5600
Jim Langston wrote:
Is the following well defined?

size_t IntVal = 65537;
unsigned short Length;

if ( IntVal static_cast<unsigned short>( -1 ) )
{
std::cout << "Value too long to fit in a short" << std::endl;
}
else
{
std::cout << "Value fits" << std::endl;
Length = static_cast<unsigned short>( IntVal );
}

What I'm actually going to be using it for is to send a length short
through sockets, and I want to ensure that the length isn't greater than
65535.
If that is want you want to check, you should say so:

if ( IntVal 65535 ) { ...

Rather than the magic number, I was thinking that
static_cast<unsigned short>( -1 ) would be better.
Why? If you want to check 65535, then presumably, your specs contain a
magic number. Your code should reflect that.
Is this well defined?
Your code has implementation defined behavior. Moreover, it is guaranteed,
that for IntVal <= 65535, the "Value fits" branch will be taken.
Will it equal 65535 in all cases where a short is a 2 byte integer?
Yes, provided your bytes have eight bits. However, your bytes maybe longer
and your shorts may have more than 2 bytes.
Now, you need to distinguish whether you want to check

(a) whether IntVal <= 65536, or
(b) whether IntVal can be faithfully represented as a short unsigned.

Your code does the later, and as far as I can see, it does so correctly.
Best

Kai-Uwe Bux
Nov 21 '06 #2

Jim Langston wrote:
Is the following well defined?

size_t IntVal = 65537;
unsigned short Length;

if ( IntVal static_cast<unsigned short>( -1 ) )
{
std::cout << "Value too long to fit in a short" << std::endl;
}
else
{
std::cout << "Value fits" << std::endl;
Length = static_cast<unsigned short>( IntVal );
}

What I'm actually going to be using it for is to send a length short through
sockets, and I want to ensure that the length isn't greater than 65535.
Rather than the magic number, I was thinking that static_cast<unsigned
short>( -1 ) would be better. Is this well defined? Will it equal 65535 in
all cases where a short is a 2 byte integer?
I doubt that can be enforced or guarenteed other than by checking
dutifully- but i may be wrong.
take a look at:
template<>
struct numeric_limits<unsigned short>
in...
#include <limits>

namespace Project {
typedef unsigned short usocket;
};

int main()
{
using Project::usocket;
using std::numeric_limits;
std::cout << "numeric_limits< usocket >::min() ";
std::cout << numeric_limits< usocket >::min();
std::cout << std::endl;
std::cout << "numeric_limits< usocket >::max() ";
std::cout << numeric_limits< usocket >::max();
std::cout << std::endl;

int n(65530);
for(size_t t = 0; t < 10; ++t)
{
std::cout << "n++ = " << n++;
usocket usock(static_cast<usocket>(n));
std::cout << "\tusock = " << usock;
std::cout << std::endl;
}
}

/*
numeric_limits< usocket >::min() 0
numeric_limits< usocket >::max() 65535
n++ = 65530 usock = 65531
n++ = 65531 usock = 65532
n++ = 65532 usock = 65533
n++ = 65533 usock = 65534
n++ = 65534 usock = 65535
n++ = 65535 usock = 0
n++ = 65536 usock = 1
n++ = 65537 usock = 2
n++ = 65538 usock = 3
n++ = 65539 usock = 4
*/

Nov 21 '06 #3
Jim Langston:
Is the following well defined?

size_t IntVal = 65537;

Slight problem here.

The range guaranteed for size_t is:

0 through 65535

On a system which has:

unsigned int : 16-Bit
unsigned long : 32-Bit
size_t : 16-Bit

, then this definition would be interpreted as:

size_t IntVal = 65537LU;

When converting to "size_t" the overflow would wrap around, making the
definition equivalent to:

size_t IntVal = 2;

unsigned short Length;

if ( IntVal static_cast<unsigned short>( -1 ) )

If you convert -1 to a unsigned integer type, then you're left with the
maximum value for that unsigned integer type. E.g.

char unsigned i = -1; char unsigned i = UCHAR_MAX;

short unsigned i = -1; short unsigned i = USHRT_MAX;

and so on...

Before the comparison takes place, the unsigned short value will be either
promoted to "int" or "unsigned int". Next, the types of the two operands will
be matched, possible yielding something like:

if ( (long unsigned)IntVal (long unsigned)USHRT_MAX )

{
std::cout << "Value too long to fit in a short" << std::endl;
}
else
{
std::cout << "Value fits" << std::endl;
Length = static_cast<unsigned short>( IntVal );
}

What I'm actually going to be using it for is to send a length short
through sockets, and I want to ensure that the length isn't greater than
65535. Rather than the magic number, I was thinking that
static_cast<unsigned short>( -1 ) would be better. Is this well
defined? Will it equal 65535 in all cases where a short is a 2 byte
integer?

To be honest, I'd have to read through the code in detail to see exactly what
you're trying to do... things to watch out for though are:

(1) Integer promotion (specifically, the possibility of "unsigned short"
promoting to "unsigned int" rather than "signed int").
(2) The range of "size_t" -- I'm not sure, but I think you could conceivably
have a system where:

typedef char unsigned size_t;

Of course, on such a system, a byte would have to be at least 16-Bit, but I
think you might want to watch out for:

sizeof(short unsigned) sizeof(size_t)

Of course, sizeof doesn't tell us how many value representation bits an
integer type has. To determine this, we can use the C-Style macro entitled
"IMAX_BITS" (Google for it), or we can use numeric_limits.

--

Frederick Gotham
Nov 21 '06 #4

"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:dO*******************@news.indigo.ie...
Jim Langston:
>Is the following well defined?

size_t IntVal = 65537;


Slight problem here.

The range guaranteed for size_t is:

0 through 65535

On a system which has:

unsigned int : 16-Bit
unsigned long : 32-Bit
size_t : 16-Bit

, then this definition would be interpreted as:

size_t IntVal = 65537LU;
On my compiler size_t is defined thusly:

#ifndef _SIZE_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
#define _SIZE_T_DEFINED
#endif

Basically an int. I'm not sure how it's defined on the 64 bit platform
(things that suggest they would go to 64 bit with the _W64 didnt'
necessarily).
>
When converting to "size_t" the overflow would wrap around, making the
definition equivalent to:

size_t IntVal = 2;

> unsigned short Length;

if ( IntVal static_cast<unsigned short>( -1 ) )


If you convert -1 to a unsigned integer type, then you're left with the
maximum value for that unsigned integer type. E.g.

char unsigned i = -1; char unsigned i = UCHAR_MAX;

short unsigned i = -1; short unsigned i = USHRT_MAX;

and so on...

Before the comparison takes place, the unsigned short value will be either
promoted to "int" or "unsigned int". Next, the types of the two operands
will
be matched, possible yielding something like:

if ( (long unsigned)IntVal (long unsigned)USHRT_MAX )

> {
std::cout << "Value too long to fit in a short" << std::endl;
}
else
{
std::cout << "Value fits" << std::endl;
Length = static_cast<unsigned short>( IntVal );
}

What I'm actually going to be using it for is to send a length short
through sockets, and I want to ensure that the length isn't greater than
65535. Rather than the magic number, I was thinking that
static_cast<unsigned short>( -1 ) would be better. Is this well
defined? Will it equal 65535 in all cases where a short is a 2 byte
integer?


To be honest, I'd have to read through the code in detail to see exactly
what
you're trying to do... things to watch out for though are:

(1) Integer promotion (specifically, the possibility of "unsigned short"
promoting to "unsigned int" rather than "signed int").
(2) The range of "size_t" -- I'm not sure, but I think you could
conceivably
have a system where:

typedef char unsigned size_t;

Of course, on such a system, a byte would have to be at least 16-Bit, but
I
think you might want to watch out for:

sizeof(short unsigned) sizeof(size_t)

Of course, sizeof doesn't tell us how many value representation bits an
integer type has. To determine this, we can use the C-Style macro entitled
"IMAX_BITS" (Google for it), or we can use numeric_limits.

--

Frederick Gotham

Nov 21 '06 #5
Jim Langston:
On my compiler size_t is defined thusly:

#ifndef _SIZE_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
#define _SIZE_T_DEFINED
#endif

Basically an int. I'm not sure how it's defined on the 64 bit platform
(things that suggest they would go to 64 bit with the _W64 didnt'
necessarily).

I've no doubt that the code might work on your platform, or even on the
majority of platforms. And I've not doubt that your compiler documentation
might even define the behaviour of the code.

All I can tell you is that the behaviour of the snippet is not defined by the
C++ Standard.

--

Frederick Gotham
Nov 21 '06 #6
On Tue, 21 Nov 2006 14:11:21 GMT, Frederick Gotham
<fg*******@SPAM.comwrote in comp.lang.c++:
Jim Langston:
Is the following well defined?

size_t IntVal = 65537;


Slight problem here.

The range guaranteed for size_t is:

0 through 65535

On a system which has:

unsigned int : 16-Bit
unsigned long : 32-Bit
size_t : 16-Bit

, then this definition would be interpreted as:

size_t IntVal = 65537LU;
No, you're quite incorrect. Check the C++ standard. An unsuffixed
decimal literal never has an unsigned type. On a platform where int
has 16 bits:

size_t IntVal = 65537;

....is exactly equivalent to:

size_t IntVal = 65537L;

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 21 '06 #7
Frederick Gotham wrote:
Jim Langston:
>On my compiler size_t is defined thusly:

#ifndef _SIZE_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
#define _SIZE_T_DEFINED
#endif

Basically an int. I'm not sure how it's defined on the 64 bit
platform (things that suggest they would go to 64 bit with the
_W64 didnt' necessarily).


I've no doubt that the code might work on your platform, or even on
the majority of platforms. And I've not doubt that your compiler
documentation might even define the behaviour of the code.
It does, even in 64 bit mode.
>
All I can tell you is that the behaviour of the snippet is not
defined by the C++ Standard.
We don't know that, unless we have checked all other defines used by the
particular implementation. With the right options set, _W64 is #define'd to
nothing. Then, if __int64 is #define'd as long, and long is big enough, it
could be correct.
Bo Persson
Nov 21 '06 #8
Bo Persson:
>I've no doubt that the code might work on your platform, or even on
the majority of platforms. And I've not doubt that your compiler
documentation might even define the behaviour of the code.

It does, even in 64 bit mode.

This is comp.lang.c++. Here's a list of newsgroups that this newsgroup is
not:

comp.lang.c++.mswindows.64
comp.lang.c++.playstation2
comp.lang.c++.whatever.implementation.you.can.find

I couldn't care less whether this code works on your interterrestial
spaceship, all I'm saying is that its behaviour is not defined by the C++
Standard. Here's another example of code I don't care about:

int main()
{
int i = 65535;

++i;
}

Will this program crash? That depends on the implementation. In the context
of portable code, the behaviour is undefined.

If you want to write platform-specific code which makes presumptions which
aren't necessitated by the Standard, then find another newsgroup.

>All I can tell you is that the behaviour of the snippet is not
defined by the C++ Standard.

We don't know that, unless we have checked all other defines used by the
particular implementation.

We know that it's not portable.

With the right options set, _W64 is #define'd
to nothing. Then, if __int64 is #define'd as long, and long is big
enough, it could be correct.

The behaviour of the code is implementation defined. Not only that though,
the implementation is free to leave the behaviour as undefined (e.g. in the
case of signed integer overflow).

--

Frederick Gotham
Nov 21 '06 #9
Frederick Gotham wrote:
Bo Persson:
>>I've no doubt that the code might work on your platform, or even
on the majority of platforms. And I've not doubt that your
compiler documentation might even define the behaviour of the
code.

It does, even in 64 bit mode.


This is comp.lang.c++. Here's a list of newsgroups that this
newsgroup is not:

comp.lang.c++.mswindows.64
comp.lang.c++.playstation2
comp.lang.c++.whatever.implementation.you.can.find

I couldn't care less whether this code works on your interterrestial
spaceship, all I'm saying is that its behaviour is not defined by
the C++ Standard. Here's another example of code I don't care about:

int main()
{
int i = 65535;

++i;
}

Will this program crash? That depends on the implementation. In the
context of portable code, the behaviour is undefined.

If you want to write platform-specific code which makes
presumptions which aren't necessitated by the Standard, then find
another newsgroup.
I hang around in other newsgroups too. Just thought you wanted it confirmed
that you were right.
>
>>All I can tell you is that the behaviour of the snippet is not
defined by the C++ Standard.

We don't know that, unless we have checked all other defines used
by the particular implementation.


We know that it's not portable.
It wasn't supposed to be portable, it is a part of one specific standard
library implementation. Whether it actually is standard conformant must be
on-topic here.
>
>With the right options set, _W64 is #define'd
to nothing. Then, if __int64 is #define'd as long, and long is big
enough, it could be correct.


The behaviour of the code is implementation defined. Not only that
though, the implementation is free to leave the behaviour as
undefined (e.g. in the case of signed integer overflow).
We can't tell just from the snippet whether it is conformant or not. It
depends on the definitions of the names _W64 and __int64, reserved to the
implementation. With the proper definitions, it just could be.
Bo Persson


Nov 22 '06 #10
Bo Persson:
We can't tell just from the snippet whether it is conformant or not. It
depends on the definitions of the names _W64 and __int64, reserved to
the implementation. With the proper definitions, it just could be.

It's implementation-defined as to whether the behaviour of the code is
undefined.

If you're interested, I started a thread over on comp.lang.c:

http://groups.google.ie/group/comp.l...f2bcf2bb366de4
4e/2156215b21253042?lnk=st&q=&rnum=1&hl=en#2156215b21 253042

(I posted on comp.lang.c rather than comp.lang.c++ as one tends to get better
answers to these kinds of questions there.)

--

Frederick Gotham
Nov 22 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Philipp | last post by:
Hello I'm working on a piece of code which I did not write and it has variables defined as: unsigned short i:13; unsigned short j:13; unsigned short k:3; As I understand the code, this...
99
by: Glen Herrmannsfeldt | last post by:
I was compiling a program written by someone else about six years ago, and widely distributed at the time. It also includes makefiles for many different systems, so I know it has been compiled...
34
by: Andy | last post by:
Hi, Are 1 through 4 defined behaviors in C? unsigned short i; unsigned long li; /* 32-bit wide */ 1. i = 65535 + 3; 2. i = 1 - 3; 3. li = (unsigned long)0xFFFFFFFF + 3; 4. li = 1...
10
by: Axel Dahmen | last post by:
Hi, I want to start a technical discussion on the fact that C# doesn't define any mathematical operators on other integral types than int. Simple things like the following just aren't possible...
6
by: karthi | last post by:
hi, I need user defined function that converts string to float in c. since the library function atof and strtod occupies large space in my processor memory I can't use it in my code. regards,...
29
by: john | last post by:
I read in the first question in the FAQ that both short and int are guaranteed to be able to hold values up to 32,767. Then why would one use an int instead of a short if short takes less space?
15
by: David Geering | last post by:
Is there any standard as to what a long and int mean or is it compiler dependent? Or furthermore architecture dependent? I know a short short long int isn't actually a recognised type, but if you...
6
by: James Curran | last post by:
In recent weeks, I've twice come upon people who consider the short- curcuited evaluation of logical && (and ||) to be just a vendor- defined compiler quirk, and recommend against depending on it....
2
by: curious2007 | last post by:
During the linking I get the following: 1>Linking... 1>main.obj : error LNK2005: "double __cdecl sigma(class curious2007::pair<double,double> const &)" (?sigma@@YANABV?$pair@NN@curious2007@@@Z)...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.