473,387 Members | 3,810 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,387 software developers and data experts.

signed/unsigned..?

Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints. Now I know that this book is
considered mostly outdated and I do use namespaces (which he also suggests
avoiding) and other things, but this particular topic has me puzzled.

The problem is that stl has a lot of size_t types that are unsigned and
since I run a no-warning policy, this forces me to do a lot of casting if
using pure int's. On the other hand, when you start to have unsigned
variables, I find that you risk getting errors that can be extremely subtle
and hard to track down.

Any advice and experience appreciated.

Søren
Jul 22 '05 #1
17 1912

"Søren Johansen" <nospam@please> wrote in message
news:3f*********************@dread11.news.tele.dk. ..
Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints. Now I know that this book is
considered mostly outdated and I do use namespaces (which he also suggests
avoiding) and other things, but this particular topic has me puzzled.

The problem is that stl has a lot of size_t types that are unsigned and
since I run a no-warning policy, this forces me to do a lot of casting if
using pure int's. On the other hand, when you start to have unsigned
variables, I find that you risk getting errors that can be extremely subtle
and hard to track down.


I don't know in what context Lakos has made the statement.
But it's not correct to assume size_t is unsigned int or anything else.
Take example of std::string.
#include <string>
int main()
{
std::string Buffer("abc");
std::string::size_type loop = Buffer.length ();
}

If you take Buffer.length() to fit into an unsigned int, the result may/may not
be correct depending on whether
std::string::size_type is actually unsigned int or not. So to be safe always
use the size types provided by the class.

HTH,
J.Schafer

..

Jul 22 '05 #2
Søren Johansen wrote:
Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints.


I don't agree with this. Especially for range checking purposes the usage of
unsigned values is preferable. Just look at the following example.

int i = ...
if ( i > 0 || i < 1000 ) doWhateverYouLike

using unsigned int this becomes
unsigned int = ...
if ( i < 1000 ) doWhateverYouLike

--
Dipl.-Inform. Hendrik Belitz
Central Laboratory of Electronics
Research Center Juelich
Jul 22 '05 #3


Hendrik Belitz wrote:

I don't agree with this. Especially for range checking purposes the usage of
unsigned values is preferable. Just look at the following example.

int i = ...
if ( i > 0 || i < 1000 ) doWhateverYouLike

using unsigned int this becomes
unsigned int = ...
if ( i < 1000 ) doWhateverYouLike


int i = ...

assert(i >= 0);

works just as well and causes an error if the constraint is violated.

Jul 22 '05 #4
Hendrik Belitz wrote:
Søren Johansen wrote:
Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints.


I don't agree with this. Especially for range checking purposes the usage
of unsigned values is preferable. Just look at the following example.


That's what I thought once too. But then it took me two days to find the
following bug in my program:

unsigned int i;
/*
....
lots of other code
.....
*/
for( i = nMax; i>0; --i ) {...

Jul 22 '05 #5
> I don't know in what context Lakos has made the statement.
But it's not correct to assume size_t is unsigned int or anything else.
Take example of std::string.
#include <string>
int main()
{
std::string Buffer("abc");
std::string::size_type loop = Buffer.length ();
}

If you take Buffer.length() to fit into an unsigned int, the result may/may not be correct depending on whether
std::string::size_type is actually unsigned int or not. So to be safe always use the size types provided by the class.


I realize this but there are some things that I dislike about it.
Consider this (made up) simple example:

class Store
{
std::vector<int> _somevector;
..other stuff..

public:
std::vector::size_type GetElementCount() { return _somevector.size(); }
void DoSomethingToElement(std::vector::size_type index);
};

Here, it seems to me that having to use the std::vector::size_type reveals
more implementation than I like in the interface. Furthermore, what if you
were to use the same index for two containers of different types?

Søren
Jul 22 '05 #6
> int i = ...
if ( i > 0 || i < 1000 ) doWhateverYouLike

using unsigned int this becomes
unsigned int = ...
if ( i < 1000 ) doWhateverYouLike


Yes but if you only want to make sure i is positive, and i has been assigned
to some unsigned value, you would have to check for i < 2147483647..
Wouldn't you? My point is that it seems that unsigned values don't really
solve the problem that they appear to. Yes, an unsigned value can never be
negative but assigning a signed value to it or comparing with a signed value
produces weird results.
The argument about the one extra bit that is gained seems to me to only be
viable in very few, special cases. Your argument is better but on the other
hand it can produce errors that are hard to identify.

Søren
Jul 22 '05 #7
Harald Grossauer wrote:

Hendrik Belitz wrote:
Søren Johansen wrote:
Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints.


I don't agree with this. Especially for range checking purposes the usage
of unsigned values is preferable. Just look at the following example.


That's what I thought once too. But then it took me two days to find the
following bug in my program:

unsigned int i;
/*
...
lots of other code
....
*/
for( i = nMax; i>0; --i ) {...


:-)
There is no problem with that. But I know what you mean.
I myself have been bitten lots of times by turning

for( i = 0; i < nMax; ++i )

around (because eg. I wanted to change the direction
in which an array is traversed) to:

for( i = nMax - 1; i >= 0; --i )

if i is unsigned this will no longer work :-)

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #8
Harald Grossauer wrote in news:3f******@sia.uibk.ac.at:
That's what I thought once too. But then it took me two days to find
the following bug in my program:

unsigned int i;
/*
...
lots of other code
....
*/
for( i = nMax; i>0; --i ) {...


There are several other options that could help here:

1) Get a better compiler and switch all warnings on.

2) Recode as:

for( unsigned i = nMax; i>0; --i ) {

3) Don't call unsigned int's i (maybe u).

4) Don't write computer programmes.

Only (4) is guaranted to work.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #9
"Søren Johansen" <nospam@please> wrote in message
news:3f*********************@dread11.news.tele.dk. ..
Hi,

in Large Scale c++ Design, John Lakos suggests that you should avoid the
"unsigned" keyword and use regular ints. Now I know that this book is
considered mostly outdated and I do use namespaces (which he also suggests
avoiding) and other things, but this particular topic has me puzzled.

The problem is that stl has a lot of size_t types that are unsigned and
since I run a no-warning policy, this forces me to do a lot of casting if
using pure int's. On the other hand, when you start to have unsigned
variables, I find that you risk getting errors that can be extremely subtle and hard to track down.

Any advice and experience appreciated.

Søren


Sorry, I have no useful advice. I have the same problem and use casting to
int far more than I would like to.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #10
Karl Heinz Buchegger wrote in news:3F**************@gascad.at:
for( i = nMax; i>0; --i ) {...
:-)


Indeed, I missed this in my first response.
There is no problem with that. But I know what you mean.
I myself have been bitten lots of times by turning

for( i = 0; i < nMax; ++i )

around (because eg. I wanted to change the direction
in which an array is traversed) to:

for( i = nMax - 1; i >= 0; --i )

if i is unsigned this will no longer work :-)


It has become atomatic for me to do:

for ( i = nMax; i-- >= 0; )
Iterators (as a concept) help here as they force you to think
in terms of the fail condition, rather that the success condition,
"until" rather than "while" maybe.

for ( i = begin(); i != end(); ++i ) reverses to
for ( i = end(); i-- != begin(); )

Though it would really be:

for( i = end(); i != begin(); )
{
--i;
// ...
}

Just in case the iterator asserts on --begin().

So we could write:

for ( i = 0; i != nMax; ++i ) and
for ( i = nMax; i-- != 0; )

Iterators have a similar problem to unsigned, in that you can't
meaningfully decrement to an element before the begining.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #11
Rob Williscroft wrote:
Karl Heinz Buchegger wrote in news:3F**************@gascad.at:
for( i = nMax; i>0; --i ) {...


:-)


Indeed, I missed this in my first response.
There is no problem with that. But I know what you mean.
I myself have been bitten lots of times by turning

for( i = 0; i < nMax; ++i )

around (because eg. I wanted to change the direction
in which an array is traversed) to:

for( i = nMax - 1; i >= 0; --i )

if i is unsigned this will no longer work :-)


It has become atomatic for me to do:

for ( i = nMax; i-- >= 0; )
Iterators (as a concept) help here as they force you to think
in terms of the fail condition, rather that the success condition,
"until" rather than "while" maybe.

for ( i = begin(); i != end(); ++i ) reverses to
for ( i = end(); i-- != begin(); )

Though it would really be:

for( i = end(); i != begin(); )
{
--i;
// ...
}

Just in case the iterator asserts on --begin().

So we could write:

for ( i = 0; i != nMax; ++i ) and
for ( i = nMax; i-- != 0; )

Iterators have a similar problem to unsigned, in that you can't
meaningfully decrement to an element before the begining.


That's why there are reverse iterators:

for ( i = begin(); i != end(); ++i ) reverses to
for ( i = rbegin(); i != rend(); ++i)

Jul 22 '05 #12
Søren Johansen wrote:
I don't know in what context Lakos has made the statement.
But it's not correct to assume size_t is unsigned int or anything
else. Take example of std::string.
#include <string>
int main()
{
std::string Buffer("abc");
std::string::size_type loop = Buffer.length ();
}

If you take Buffer.length() to fit into an unsigned int, the result may/may not
be correct depending on whether
std::string::size_type is actually unsigned int or not. So to be
safe

always
use the size types provided by the class.


I realize this but there are some things that I dislike about it.
Consider this (made up) simple example:

class Store
{
std::vector<int> _somevector;
..other stuff..

public:
std::vector::size_type GetElementCount() { return
_somevector.size(); } void
DoSomethingToElement(std::vector::size_type index);
};

Here, it seems to me that having to use the std::vector::size_type
reveals more implementation than I like in the interface.


Simple solution:

class Store
{
std::vector<int> _somevector;
..other stuff..

public:
typedef std::vector<int>::size_type size_type;

size_type GetElementCount() { return _somevector.size(); }
void DoSomethingToElement(size_type index);
};

Furthermore, what if you were to use the same index for two containers
of different types?


What for?

Jul 22 '05 #13
Rob Williscroft wrote:
for( i = nMax - 1; i >= 0; --i )

if i is unsigned this will no longer work :-)


It has become atomatic for me to do:

for ( i = nMax; i-- >= 0; )


Thank's for that! I never realized that solution to this problem.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #14

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...
Rob Williscroft wrote:
for( i = nMax - 1; i >= 0; --i )

if i is unsigned this will no longer work :-)


It has become atomatic for me to do:

for ( i = nMax; i-- >= 0; )


Thank's for that! I never realized that solution to this problem.


Thanks for what? If 'i' is indeed unsigned, it still doesn't work.

Cheers!

- Risto -

Jul 22 '05 #15
Risto Lankinen wrote in news:Nz******************@news2.nokia.com:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...
Rob Williscroft wrote:
>
> > for( i = nMax - 1; i >= 0; --i )
> >
> > if i is unsigned this will no longer work :-)
> >
>
> It has become atomatic for me to do:
>
> for ( i = nMax; i-- >= 0; )


Thank's for that! I never realized that solution to this problem.


Thanks for what? If 'i' is indeed unsigned, it still doesn't work.


Thanks for the correction, I should have writen:

for ( i = nMax; i-- > 0; )

Though I did get it write later in the post:

for ( i = nMax; i-- != 0; )

It maybe that the single point of failure in the second version is
less error prone (though it could have been a cut paste typo', I
really can't remember).

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #16
On Fri, 12 Dec 2003 16:01:29 +0100, Harald Grossauer
<ha**************@uibk.ac.at> wrote:
unsigned int i;
/*
...
lots of other code
....
*/
for( i = nMax; i>0; --i ) {...


Well, Borland C++ Builder 5 (for one) will issue a helpful warning
here: "the condition is always true" ...

It also helps to avoid using variable names like "i" if you need them
in scope for more than a couple of lines or so.
--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #17
Sorry, it only gives the warning if i>=0. I shouldn't post so
quickly...
--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #18

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

Similar topics

19
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...
3
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 ...
9
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...
9
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...
10
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...
20
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...
10
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...
7
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...
6
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...
39
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...

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.