Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 82619
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T21:38:43+00:00 2026-05-10T21:38:43+00:00

I myself am convinced that in a project I’m working on signed integers are

  • 0

I myself am convinced that in a project I’m working on signed integers are the best choice in the majority of cases, even though the value contained within can never be negative. (Simpler reverse for loops, less chance for bugs, etc., in particular for integers which can only hold values between 0 and, say, 20, anyway.)

The majority of the places where this goes wrong is a simple iteration of a std::vector, often this used to be an array in the past and has been changed to a std::vector later. So these loops generally look like this:

for (int i = 0; i < someVector.size(); ++i) { /* do stuff */ } 

Because this pattern is used so often, the amount of compiler warning spam about this comparison between signed and unsigned type tends to hide more useful warnings. Note that we definitely do not have vectors with more then INT_MAX elements, and note that until now we used two ways to fix compiler warning:

for (unsigned i = 0; i < someVector.size(); ++i) { /*do stuff*/ } 

This usually works but might silently break if the loop contains any code like ‘if (i-1 >= 0) …’, etc.

for (int i = 0; i < static_cast<int>(someVector.size()); ++i) { /*do stuff*/ } 

This change does not have any side effects, but it does make the loop a lot less readable. (And it’s more typing.)

So I came up with the following idea:

template <typename T> struct vector : public std::vector<T> {     typedef std::vector<T> base;      int size() const     { return base::size(); }     int max_size() const { return base::max_size(); }     int capacity() const { return base::capacity(); }      vector()                  : base() {}     vector(int n)             : base(n) {}     vector(int n, const T& t) : base(n, t) {}     vector(const base& other) : base(other) {} };  template <typename Key, typename Data> struct map : public std::map<Key, Data> {     typedef std::map<Key, Data> base;     typedef typename base::key_compare key_compare;      int size() const     { return base::size(); }     int max_size() const { return base::max_size(); }      int erase(const Key& k) { return base::erase(k); }     int count(const Key& k) { return base::count(k); }      map() : base() {}     map(const key_compare& comp) : base(comp) {}     template <class InputIterator> map(InputIterator f, InputIterator l) : base(f, l) {}     template <class InputIterator> map(InputIterator f, InputIterator l, const key_compare& comp) : base(f, l, comp) {}     map(const base& other) : base(other) {} };  // TODO: similar code for other container types 

What you see is basically the STL classes with the methods which return size_type overridden to return just ‘int’. The constructors are needed because these aren’t inherited.

What would you think of this as a developer, if you’d see a solution like this in an existing codebase?

Would you think ‘whaa, they’re redefining the STL, what a huge WTF!’, or would you think this is a nice simple solution to prevent bugs and increase readability. Or maybe you’d rather see we had spent (half) a day or so on changing all these loops to use std::vector<>::iterator?

(In particular if this solution was combined with banning the use of unsigned types for anything but raw data (e.g. unsigned char) and bit masks.)

  • 1 1 Answer
  • 3 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T21:38:44+00:00Added an answer on May 10, 2026 at 9:38 pm

    I made this community wiki… Please edit it. I don’t agree with the advice against ‘int’ anymore. I now see it as not bad.

    Yes, i agree with Richard. You should never use 'int' as the counting variable in a loop like those. The following is how you might want to do various loops using indices (althought there is little reason to, occasionally this can be useful).

    Forward

    for(std::vector<int>::size_type i = 0; i < someVector.size(); i++) {     /* ... */ } 

    Backward

    You can do this, which is perfectly defined behaivor:

    for(std::vector<int>::size_type i = someVector.size() - 1;      i != (std::vector<int>::size_type) -1; i--) {     /* ... */ } 

    Soon, with c++1x (next C++ version) coming along nicely, you can do it like this:

    for(auto i = someVector.size() - 1; i != (decltype(i)) -1; i--) {     /* ... */ } 

    Decrementing below 0 will cause i to wrap around, because it is unsigned.

    But unsigned will make bugs slurp in

    That should never be an argument to make it the wrong way (using 'int').

    Why not use std::size_t above?

    The C++ Standard defines in 23.1 p5 Container Requirements, that T::size_type , for T being some Container, that this type is some implementation defined unsigned integral type. Now, using std::size_t for i above will let bugs slurp in silently. If T::size_type is less or greater than std::size_t, then it will overflow i, or not even get up to (std::size_t)-1 if someVector.size() == 0. Likewise, the condition of the loop would have been broken completely.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've convinced myself that they can't. Take for example: 4 4 + 4 /
Got myself in a bit of a pickle here ... working on a CMS
I wrote myself a little downloading application so that I could easily grab a
I'm teaching myself Python and my most recent lesson was that Python is not
Myself and a colleague have a dispute about which of the following is more
I've found myself increasingly unsatisfied with the DataSet/DataTable/DataRow paradigm in .Net, mostly because it's
I frequently find myself writing code like this: List<int> list = new List<int> {
I find myself writing delegates occasionally for really simple functions (take no arguments and
Often I find myself interacting with files in some way but after writing the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.