signed/unsigned..?

Discussion in 'C++' started by Søren Johansen, Dec 12, 2003.

  1. 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
     
    Søren Johansen, Dec 12, 2003
    #1
    1. Advertising

  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
     
    Hendrik Belitz, Dec 12, 2003
    #2
    1. Advertising

  3. "Søren Johansen" <nospam@please> wrote in message
    news:3fd9a963$0$182$...
    > 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

    ..
     
    Josephine Schafer, Dec 12, 2003
    #3
  4. Søren Johansen

    lilburne Guest

    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.
     
    lilburne, Dec 12, 2003
    #4
  5. 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 ) {...
     
    Harald Grossauer, Dec 12, 2003
    #5
  6. > 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
     
    Søren Johansen, Dec 12, 2003
    #6
  7. > 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
     
    Søren Johansen, Dec 12, 2003
    #7
  8. 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
     
    Karl Heinz Buchegger, Dec 12, 2003
    #8
  9. Harald Grossauer wrote in news::

    > 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/
     
    Rob Williscroft, Dec 12, 2003
    #9
  10. Søren Johansen

    Cy Edmunds Guest

    "Søren Johansen" <nospam@please> wrote in message
    news:3fd9a963$0$182$...
    > 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/
     
    Cy Edmunds, Dec 12, 2003
    #10
  11. Karl Heinz Buchegger wrote in news::

    >> 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/
     
    Rob Williscroft, Dec 12, 2003
    #11
  12. Søren Johansen

    Rolf Magnus Guest

    Rob Williscroft wrote:

    > Karl Heinz Buchegger wrote in news::
    >
    >>> 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)
     
    Rolf Magnus, Dec 12, 2003
    #12
  13. Søren Johansen

    Rolf Magnus Guest

    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?
     
    Rolf Magnus, Dec 12, 2003
    #13
  14. 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
     
    Karl Heinz Buchegger, Dec 12, 2003
    #14
  15. "Karl Heinz Buchegger" <> wrote in message
    news:...
    > 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 -
     
    Risto Lankinen, Dec 16, 2003
    #15
  16. Risto Lankinen wrote in news:NzADb.4898$:

    >
    > "Karl Heinz Buchegger" <> wrote in message
    > news:...
    >> 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/
     
    Rob Williscroft, Dec 16, 2003
    #16
  17. On Fri, 12 Dec 2003 16:01:29 +0100, Harald Grossauer
    <> 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
     
    Bob Hairgrove, Dec 16, 2003
    #17
  18. Sorry, it only gives the warning if i>=0. I shouldn't post so
    quickly...


    --
    Bob Hairgrove
     
    Bob Hairgrove, Dec 16, 2003
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeremy Pyle
    Replies:
    3
    Views:
    52,760
    Mike Treseler
    Jun 28, 2003
  2. Patrick

    signed to unsigned

    Patrick, Jun 7, 2004, in forum: VHDL
    Replies:
    1
    Views:
    5,568
    Ralf Hildebrandt
    Jun 7, 2004
  3. kyrpa83
    Replies:
    1
    Views:
    630
    kyrpa83
    Oct 17, 2007
  4. Rob1bureau
    Replies:
    1
    Views:
    814
    joris
    Feb 27, 2010
  5. pozz
    Replies:
    12
    Views:
    748
    Tim Rentsch
    Mar 20, 2011
Loading...

Share This Page