473,889 Members | 1,679 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

signed vs unsigned

LuB
This isn't a C++ question per se ... but rather, I'm posting this bcs I
want the answer from a C++ language perspective. Hope that makes sense.

I was reading Peter van der Linden's "Expert C Programming: Deep C
Secrets" and came across the following statement:

"Avoid unnecessary complexity by minimizing your use of unsigned types.
Specifically, don't use an unsigned type to represent a quantity just
because it will never be negative (e.g., "age" or "national_debt" )."

Admittedly, I minimize comments in my code. I use them when necessary
but try to limit them to one or two lines. I just don't like their
aesthetic affect in the source. I find the code much harder to read
littered with paragraphs of explanations.

I find the code easier to read when broken up with appropriate newlines
and small, short comments acting as headings.

So - that effectually means that I try my darndest to write
self-describing code. Shorter functions, self-explanatory names for
functions and variable names, etc. Sometimes exceessive commenting is
necessary, but as a whole, I tend to avoid it.

I'm really enjoying Peter's book, but I find this comment hard to
swallow considering that if an age or array index can never be negative
- I would want to illustrate that with an apporpriate choice of type -
namely, unsigned int.

Am I in the minority here? Is my predilection considered poor style?

I guess, from the compiler's standpoint ... using int everywhere is
more portable ... since comparison's against unsigned int can vary
between K&R and ANSI C.

I'm not incurring some type of performance penalty for such decisions
am I?

Thanks in advance,

-Luther

Feb 21 '06
26 36109

Alf P. Steinbach wrote:
* Neil Cerutti:
On 2006-02-21, Tomás <NU**@NULL.NULL > wrote:
My first rule is to write "const" wherever I can.
(except for return types).

My second rule is to write "unsigned" wherever I can.


I don't agree with that rule.
Thus I'll write:

unsigned GetDogAge(unsig ned const age)
{
return age * 7;
}


What do you expect to happen if a client passes in an negative int?

The argument is not in the domain, yet the error has been rendered
impossible to detect or recover from.


I don't disagree with your viewpoint regarding using or not using
unsigned whenever possible; I think both are valid viewpoints, and as
with indentation the main thing is to be consistent in one's choices.

However, I disagree with your reason!

With the unsigned argument a validity test might go like

assert( age < 200 ); // unsigned validity test.

With a signed argument the test might go like

assert( age >= 0 ); // signed validity test.
assert( age < 200 ); // more signed validity test.

Now, first of all that demonstrates the "impossible to detect" is simply
incorrect, and second, in my view it demonstrates a slight superiority
for unsigned in this particular case, with respect to validity testing.


I believe he is talking about something like this:
#include <iostream>
using namespace std;

unsigned int GetDogAge(unsig ned int age)
{
return age * 7;
}

int main(int argc, char* argv[])
{
int t = -5;
unsigned int x = GetDogAge(t);

cout << x;

int y; cin >> y;

return 0;
}

------ Build started: Project: Playground, Configuration: Debug Win32
------

Compiling...
Playground.cpp
Linking...

Build log was saved at
"file://c:\src\Playgrou nd\Playground\D ebug\BuildLog.h tm"
Playground - 0 error(s), 0 warning(s)
---------------------- Done ----------------------

Build: 1 succeeded, 0 failed, 0 skipped

Output is, "4294967261 ."

It is an interesting point.

Feb 21 '06 #11
Daniel T. wrote:
In article <11************ **********@f14g 2000cwb.googleg roups.com>,
ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and
you use signed then you always have to check it. Simply defining the
type as unsigned gets rid of all that as well as documenting your
domain.
And the bad thing about unsigned is that if code would otherwise make
the value negative, you can't check it. IE

void foo( unsigned s ) {
// at this point s == 4294966272
// is it an error (s came in as -1024) or
// does the client really want us to deal with that number?
}

Bjarne Stroustrup says, "The unsigned integer types are ideal for uses
that treat storage as a bit array. Using an unsigned instead of an int
to gain one more bit to represent positive integers is almost never a
good idea. Attempts to ensure that some values are positive by declaring
variables unsigned will typically be defeated by the implicit conversion
rules."


Sounds like a good excuse to write an unsigned_int class:

#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >

class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0

)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};

int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);

unsigned_int n5 = 1; // Error!
}

reagrds
Andy Little

Feb 21 '06 #12

Daniel T. wrote:
In article <11************ **********@f14g 2000cwb.googleg roups.com>,
ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and
you use signed then you always have to check it. Simply defining the
type as unsigned gets rid of all that as well as documenting your
domain.
And the bad thing about unsigned is that if code would otherwise make
the value negative, you can't check it. IE

void foo( unsigned s ) {
// at this point s == 4294966272
// is it an error (s came in as -1024) or
// does the client really want us to deal with that number?
}

Bjarne Stroustrup says, "The unsigned integer types are ideal for uses
that treat storage as a bit array. Using an unsigned instead of an int
to gain one more bit to represent positive integers is almost never a
good idea. Attempts to ensure that some values are positive by declaring
variables unsigned will typically be defeated by the implicit conversion
rules."


Sounds like a good excuse for an unsigned_int class ...

#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >

class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0

)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};

int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);

unsigned_int n5 = 1; // Error!
}

reagrds
Andy Little

Feb 21 '06 #13
Daniel T. wrote:
In article <11************ **********@f14g 2000cwb.googleg roups.com>,
ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and
you use signed then you always have to check it. Simply defining the
type as unsigned gets rid of all that as well as documenting your
domain.
And the bad thing about unsigned is that if code would otherwise make
the value negative, you can't check it. IE

void foo( unsigned s ) {
// at this point s == 4294966272
// is it an error (s came in as -1024) or
// does the client really want us to deal with that number?
}

Bjarne Stroustrup says, "The unsigned integer types are ideal for uses
that treat storage as a bit array. Using an unsigned instead of an int
to gain one more bit to represent positive integers is almost never a
good idea. Attempts to ensure that some values are positive by declaring
variables unsigned will typically be defeated by the implicit conversion
rules."


Sounds like a good excuse to write an unsigned_int class:

#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >

class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0

)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};

int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);

unsigned_int n5 = 1; // Error!
}

reagrds
Andy Little

Feb 21 '06 #14

a...@servocomm. freeserve.co.uk wrote:

Sorry
Sorry
Sorry for posting 3 times. Browser hung up

regards
Andy Little

Feb 21 '06 #15
* ro**********@gm ail.com:
Alf P. Steinbach wrote:
* Neil Cerutti:
On 2006-02-21, Tomás <NU**@NULL.NULL > wrote:
My first rule is to write "const" wherever I can.
(except for return types).

My second rule is to write "unsigned" wherever I can.
I don't agree with that rule.

Thus I'll write:

unsigned GetDogAge(unsig ned const age)
{
return age * 7;
}
What do you expect to happen if a client passes in an negative int?

The argument is not in the domain, yet the error has been rendered
impossible to detect or recover from. I don't disagree with your viewpoint regarding using or not using
unsigned whenever possible; I think both are valid viewpoints, and as
with indentation the main thing is to be consistent in one's choices.

However, I disagree with your reason!

With the unsigned argument a validity test might go like

assert( age < 200 ); // unsigned validity test.

With a signed argument the test might go like

assert( age >= 0 ); // signed validity test.
assert( age < 200 ); // more signed validity test.

Now, first of all that demonstrates the "impossible to detect" is simply
incorrect, and second, in my view it demonstrates a slight superiority
for unsigned in this particular case, with respect to validity testing.


I believe he is talking about something like this:

[snip] int t = -5;
unsigned int x = GetDogAge(t);


Yes, that would be caught by the validity test for unsigned formal arg,

assert( age < 200 );

Cheers,

- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 21 '06 #16
LuB wrote:
This isn't a C++ question per se ... but rather, I'm posting this bcs I
want the answer from a C++ language perspective. Hope that makes sense.

I was reading Peter van der Linden's "Expert C Programming: Deep C
Secrets" and came across the following statement:

"Avoid unnecessary complexity by minimizing your use of unsigned types.
Specifically, don't use an unsigned type to represent a quantity just
because it will never be negative (e.g., "age" or "national_debt" )."

Admittedly, I minimize comments in my code. I use them when necessary
but try to limit them to one or two lines. I just don't like their
aesthetic affect in the source. I find the code much harder to read
littered with paragraphs of explanations.

I find the code easier to read when broken up with appropriate newlines
and small, short comments acting as headings.

So - that effectually means that I try my darndest to write
self-describing code. Shorter functions, self-explanatory names for
functions and variable names, etc. Sometimes exceessive commenting is
necessary, but as a whole, I tend to avoid it.

I'm really enjoying Peter's book, but I find this comment hard to
swallow considering that if an age or array index can never be negative
- I would want to illustrate that with an apporpriate choice of type -
namely, unsigned int.

Am I in the minority here? Is my predilection considered poor style?

I guess, from the compiler's standpoint ... using int everywhere is
more portable ... since comparison's against unsigned int can vary
between K&R and ANSI C.

I'm not incurring some type of performance penalty for such decisions
am I?

Thanks in advance,

-Luther
It's like driving on the left or driving on the right. It's basically
an
arbitrary choice (now that we drive cars), it's just good if everyone
makes the same arbitrary choice. That is if there's more than
just you on the road, which is analagous to maintaining
existing code or heavily using libraries written by others.

Many compilers generate (to me helpful) warnings if you do a, <, <=, >= comparison between a signed and unsigned.

Many also generate (to me useless) warnings if you do a
== or != comparison between a signed and unsigned. So,
you can end up with alot of static_casts to get rid of the
warnings.

For some reason, if an unsigned type is used in an expression
where it has to be implicitly converted to a larger type, it
will be converted to a signed larger type. As far as I can
see, this rule has no practical effect, other than to give
some compilers an excuse to generate unnecessary
warnings. (I guess it could change the results when
using bitwise ops on variables of different sizes, which
to me is a bad idea anyway.) So, that's one reason to prefer
signed. But, like you, I prefer to use unsigned for variables that
should always be nonnegative, to make the intent clear.

Feb 21 '06 #17
Daniel T. wrote:
In article <11************ **********@f14g 2000cwb.googleg roups.com>,
ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and
you use signed then you always have to check it. Simply defining the
type as unsigned gets rid of all that as well as documenting your
domain.


And the bad thing about unsigned is that if code would otherwise make
the value negative, you can't check it. IE


Surely overflow and underflow are a problem with both signed and unsigned?

These are often situations where you are unable to check validity
without domain specific knowledge - I don't see how signed unsigned vary
in that regard.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 22 '06 #18

LuB wrote:
This isn't a C++ question per se ... but rather, I'm posting this bcs I
want the answer from a C++ language perspective. Hope that makes sense.

I was reading Peter van der Linden's "Expert C Programming: Deep C
Secrets" and came across the following statement:

"Avoid unnecessary complexity by minimizing your use of unsigned types.
Specifically, don't use an unsigned type to represent a quantity just
because it will never be negative (e.g., "age" or "national_debt" )."

Admittedly, I minimize comments in my code. I use them when necessary
but try to limit them to one or two lines. I just don't like their
aesthetic affect in the source. I find the code much harder to read
littered with paragraphs of explanations.

I find the code easier to read when broken up with appropriate newlines
and small, short comments acting as headings.

So - that effectually means that I try my darndest to write
self-describing code. Shorter functions, self-explanatory names for
functions and variable names, etc. Sometimes exceessive commenting is
necessary, but as a whole, I tend to avoid it.
Self-explanatory names are good.
I'm really enjoying Peter's book, but I find this comment hard to
swallow considering that if an age or array index can never be negative
- I would want to illustrate that with an apporpriate choice of type -
namely, unsigned int.
Why would you want to illustrate it with an appropriate choice of type?
I would want to illustrate it with a self-explanatory name.
Am I in the minority here? Is my predilection considered poor style?

I guess, from the compiler's standpoint ... using int everywhere is
more portable ... since comparison's against unsigned int can vary
between K&R and ANSI C.

I'm not incurring some type of performance penalty for such decisions
am I?


This question comes up regularly. Search the history of the newsgroup
and you will find plenty of discussion. But I am slightly surprised to
see this thread get to nearly 20 posts (as far as I can see so far)
without anyone mentioning the subtraction issue.

Personally, I do not accept that argument for unsigned as documentation
to mean "negative values make no sense here". The variable name (age,
buffer_size, radius) serves that purpose. Comparison with const is not
valid. const is useful because it is enforced by the compiler. unsigned
is not enforced. -1 years does not make sense for age, but neither does
4294967295 years. At best, using unsigned has only documented one end
of your range. And since the variable name has already achieved that,
you haven't gained anything.

But that's not the only reason I don't use unsigned for these sort of
quantities. In general, subtracting one person's age from another in
the real world yields a signed result but in C++ subtracting one
unsigned quantity from another yields an unsigned result.

<quote Kaz Kylheku (in post number 28 as I write this)>
http://groups.google.co.uk/group/com...236f41f9de66f8

Thus code like if (buffer_space - requested_paylo ad > header_size)
is broken if unsigned integers are used, and there was no prior check
that the requested_paylo ad isn't larger than the buffer.

</quote>

Both signed and unsigned arithmetic in C++ behave just like real world
integer arithmetic until you reach the minimum and maximum values for
those types. The difference is that for signed, the correlation between
the real world and C++ breaks down at + or - a very big number, whereas
for unsigned, the correlation between the real world and C++ breaks
down at zero and a (different) very big number.

In other words, if I use unsigned, I am very close to the edge of the
domain in which C++ arithmetic corresponds to the real world. If I use
signed, I am comfortably in the middle of that domain and the
extremities where I have to start coding for special cases are far, far
away from any number that I am likely to ever want to use for an age or
a length or a size, or I am likely to ever end up with by doing
arithmetic with those quantities.

Gavin Deane

Feb 22 '06 #19
Gavin Deane wrote:

But that's not the only reason I don't use unsigned for these sort of
quantities. In general, subtracting one person's age from another in
the real world yields a signed result but in C++ subtracting one
unsigned quantity from another yields an unsigned result.

<quote Kaz Kylheku (in post number 28 as I write this)>
http://groups.google.co.uk/group/com...236f41f9de66f8

Thus code like if (buffer_space - requested_paylo ad > header_size)
is broken if unsigned integers are used, and there was no prior check
that the requested_paylo ad isn't larger than the buffer.

</quote>
That's a very good point.
Both signed and unsigned arithmetic in C++ behave just like real world
integer arithmetic until you reach the minimum and maximum values for
those types. The difference is that for signed, the correlation between
the real world and C++ breaks down at + or - a very big number, whereas
for unsigned, the correlation between the real world and C++ breaks
down at zero and a (different) very big number.

In other words, if I use unsigned, I am very close to the edge of the
domain in which C++ arithmetic corresponds to the real world. If I use
signed, I am comfortably in the middle of that domain and the
extremities where I have to start coding for special cases are far, far
away from any number that I am likely to ever want to use for an age or
a length or a size, or I am likely to ever end up with by doing
arithmetic with those quantities.


In an ideal world, we would probably all do range checking more often
than we do.

I always say you make your own luck, with signed types you're more lucky!

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 22 '06 #20

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

Similar topics

19
6490
by: MiniDisc_2k2 | last post by:
Okay, here's a question about the standard. What does it say about unsigned/signed mismatches in a comparison statement: char a = 3; unsigned char b = 255; if (a<b) Now what's the real answer here? If a is converted to unsigned, then b>a. But, if b is converted to signed,then a>b. What's the correct coversion (what is the compiler supposed to do?)
3
31523
by: Siemel Naran | last post by:
Hi. Is there a way to convert the type signed int to the type unsigned int, char to unsigned char, signed char to unsigned char, and so on for all the fundamental integer types? Something like template <> struct to_unsigned<signed int> : public std::unary_function<signed int, unsigned int> { unsigned int operator()(signed int x) const { return x; } };
9
4966
by: Fred Ma | last post by:
Hello, I've been trying to clear up a confusion about integer promotions during expression evaluation. I've checked the C FAQ and C++ FAQ (they are different languages, but I was hoping one would clear up the confusion), as well as googling groups and the web. The confusion is that for a binary operator,
9
4188
by: dam_fool_2003 | last post by:
For int data type the default range starts from signed to unsigned. If we don't want negative value we can force an unsigned value. The same goes for long also. But I don't understand why we have signed char which is -256. Does it means that we can assign the same ASCII value to both signed and unsigned. That means the ASCII value can be represented with a type of signed char and also unsigned char? For example int main(void) {
10
15688
by: tinesan | last post by:
Hello fellow C programmers, I'm just learning to program with C, and I'm wondering what the difference between signed and unsigned char is. To me there seems to be no difference, and the standard doesn't even care what a normal char is (because signed and unsigned have equal behavior). For example if someone does this: unsigned char a = -2; /* or = 254 */
20
5380
by: Hanzac Chen | last post by:
Hi, I don't understand why this could happen? The Code 1 will output `fff9' and the Code 2 will output `1' How could the `mod 8' not have effect? /* Code 1 */ #include <stdio.h> #include <stdlib.h>
10
3322
by: =?iso-8859-2?B?SmFuIFJpbmdvuQ==?= | last post by:
Hello everybody, this is my first post to a newsgroup at all. I would like to get some feedback on one proposal I am thinking about: --- begin of proposal --- Proposal to add signed/unsigned modifier to class declarations to next revision of C++ programming language
7
5058
by: somenath | last post by:
Hi All, I am trying to undestand "Type Conversions" from K&R book.I am not able to understand the bellow mentioned text "Conversion rules are more complicated when unsigned operands are involved. The problem is that comparisons between signed and unsigned values are machine- dependent, because they depend on the sizes of the various integer types. For example, suppose that int is 16 bits
6
6475
by: Kislay | last post by:
Consider the following code snippet unsigned int i=10; int j= - 2; // minus 2 if(i>j) cout<<"i is greater"; else cout<<"j is greater"; Since i is unsigned , j is greater . I know why , but vaguely . Can
39
2682
by: Juha Nieminen | last post by:
I was once taught that if some integral value can never have negative values, it's a good style to use an 'unsigned' type for that: It's informative, self-documenting, and you are not wasting half of the value range for values which you will never be using. I agreed with this, and started to always use 'unsigned' whenever negative values wouldn't make any sense. I did this for years. However, I slowly changed my mind: Doing this often...
0
9969
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9810
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10794
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10896
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10443
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7999
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5830
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6029
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4650
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.