1

I have written some code for detecting the Strongly Connected Components. It runs fine, but for one warning:

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

I understand it is for the following notorious code snippet (as pointed out in this SO answer):

int i;                              //instead of size_t i;
vector< int > sorted;
...

for(i=sorted.size()-1; i>=0; --i) {
    ...
}

But how do I get rid of this warning? If I write size_t i;, then I get a segmentation fault (and a Time Limit Exceeded on online judges, for which the code is written). If I use int i; then I get the above warning (with which I am uncomfortable, and so is my professor).

So, any work around?

Edit: The code works fine on declaring i as an int. There is no vector over (or under) flow. Also, I do understand why there is a segmentation fault. My question precisely is, how do I circumvent it (without any warning)?

Community
  • 1
  • 1
  • Use unsigned int instead of int. – Maria Ivanova Jun 27 '16 at 07:19
  • Tried it. But I get the same warning. –  Jun 27 '16 at 07:21
  • 2
    Segfault is caused by i>=0. It never ends loop. – KIIV Jun 27 '16 at 07:21
  • You are underflowing your size_t / unsigned int – Trevor Hickey Jun 27 '16 at 07:21
  • > Segfault is caused by i>=0. It never ends loop. Unsigned values are _always_ `>= 0`. – Roger Lipscombe Jun 27 '16 at 07:21
  • @KIIV, correct; but that is because `i` is unsigned. The code works like a charm on changing it to `signed`. –  Jun 27 '16 at 07:21
  • You have two options: count from size to 1 (zero stops the loop) and index by i-1, or reverse iterator – KIIV Jun 27 '16 at 07:23
  • In case if you used `size_t i;` then in the for loop when `i == 0` then the body of loop will be executed and after that `--i` will get executed. Now since `size_t` is `unsigned int` on most platform then this `--i` will result in assigning the max value [4294967295] to `i` and this will cause segfault. – sameerkn Jun 27 '16 at 07:25
  • @RogerLipscombe, yeah but my vector contains element at position `0`; so how do I access it without the warning? –  Jun 27 '16 at 07:25
  • I fully concur with Trevor's answer using reverse iteration. But if you *really* wanted to use indexes to iterate backward, `for (auto i=sorted.size(); i-- > 0;) { ...}` – WhozCraig Jun 27 '16 at 07:27
  • Cast the size to int: `for(int i= (int)sorted.size()-1; i>=0; --i)`. It should be safe unless sorted.size() > MAX_INT, which is very unlikely – Can Nguyen Jun 27 '16 at 07:36

2 Answers2

3

Since you are using std::vector, you may want to switch your raw indexing with iterators.

for (auto it = sorted.rbegin(); it != sorted.rend(); ++it) {
  // ...
}

This would:

  • iterate over your container backwards
  • remove the "sign-compare" warning
  • make the code objectively more readable and safer
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
1

You might control the value of i one more than the index in the for loop, to avoid trying to make i less than 0, which will cause overflow when i is unsigned.

for (i = sorted.size(); i > 0; ) {
    --i;
    ...
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405