• Create Account

## Comparing a negative value against std::vector.size()

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

10 replies to this topic

### #1stitchs  Members

1361
Like
0Likes
Like

Posted 15 December 2012 - 04:23 PM

Hello community,

I am having a minor issue in my code, I have replaced an Integer variable with the std::vector.size() in a comparison statement (please see below):

[source lang="cpp"]if(selectedOption_ > (optionsList_.size() - 1)) { selectedOption_ = (optionsList_.size() - 1); } else if(selectedOption_ < firstSelectableOption_) { // Highlighted option does not trigger as going less than 0. selectedOption_ = firstSelectableOption_; }[/source]

Before, I compared SelectedOption to an Integer (numOptions) and this worked as I expected, if it went greater than said number then it would be reset to numOptions, else if it when less than 0(firstSelectableOption), it would be set to zero.

Once I replaced it with size(), if the SelectedOption goes less than zero, it triggers the 'greater-than' clause and sets the SelectedOption equal to whatever the size()-1 is. I have looked through the debugger and the numbers are coming back as expected: SelectedOption becomes -1, and size in this instance being 2. So what is going on here. The quick-fix solution I am using is this:

[source lang="cpp"]if(selectedOption_ < firstSelectableOption_) { // Highlighted option does not trigger as going less than 0. selectedOption_ = firstSelectableOption_; } else if(selectedOption_ > (optionsList_.size() -1)) { selectedOption_ = (optionsList_.size() - 1); }[/source]

This ensures that the check for going less than zero occurs first, which solves the issue I am having, but does not answer the question it puts forward.

In short, is there something I am missing that would be firing the if-else in reverse order. Also, I have checked and am not setting size equal to something different elsewhere.

Regards,

Stitchs.

### #2JTippetts  Moderators

12317
Like
0Likes
Like

Posted 15 December 2012 - 04:29 PM

std::vector::size is an unsigned type, per the docs. Subtracting 1 from an unsigned 0 value doesn't give you a negative value, it gives you the maximum value the unsigned type can hold. Edit: Furthermore if the negative integer you are trying to compare gets implicitly cast to unsigned int, then it's no longer negative, just very large positive.

Edited by JTippetts, 15 December 2012 - 04:32 PM.

### #3stitchs  Members

1361
Like
0Likes
Like

Posted 15 December 2012 - 04:37 PM

In this instance of the class, size is always 2, it is never 0. That did cross my mind at one point, but I thought, as long as my Integer is not unsigned, then this would not be an issue? When would my negative Integer get cast to an unsigned int? Does this happen in the comparison at all?

Regards,

Stitchs.

### #4JTippetts  Moderators

12317
Like
1Likes
Like

Posted 15 December 2012 - 04:52 PM

When would my negative Integer get cast to an unsigned int? Does this happen in the comparison at all?

Regards,

Stitchs.

Yes.

Your compiler should be warning you about the signed to unsigned comparison, as well. It's a good idea to pay attention to those kinds of warnings, as subtle bugs like this can result.

### #5Servant of the Lord  Members

33539
Like
0Likes
Like

Posted 15 December 2012 - 05:16 PM

A possible solution would be to cast your unsigned value (the size_t result from vector<>.size()) to a signed value.
if(myInt < (int)vector.size())

Side-effects: if your size_t ever reaches higher than 31^2 (about two billion), your value will likely loop around to -31^2 (around negative two billion).

if(selectedOption_ >= int(optionsList_.size()))
{

}
else if(selectedOption_ < firstSelectableOption_)
{

}

Edited by Servant of the Lord, 15 December 2012 - 05:20 PM.

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #6Yrjö P.  Members

1416
Like
0Likes
Like

Posted 15 December 2012 - 05:19 PM

You can fix this simply by moving the -1 on the other side of the inequality as +1, so you'll no longer get underflows.

5832
Like
0Likes
Like

Posted 15 December 2012 - 05:21 PM

You'll just get an overflow if selectedOption_ == INT_MAX ;) but a lot less likely
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

### #8stitchs  Members

1361
Like
0Likes
Like

Posted 15 December 2012 - 05:33 PM

I get it now, Visual Studio wasn't showing me this warning on compilation. I have just performed a clean build, and it is one of the first warnings to show itself. Seems like my initial (if brief) thought actually was the case. Thanks all for your speedy responses, I'll get on the case now.

Regards,

Stitchs.

5832
Like
0Likes
Like

Posted 15 December 2012 - 05:36 PM

Also, whack up your warning level to the highest possible (level 4 I think), and fix all of them. If you get warnings from 3rd party headers, you can use #pragma warning(push:####) and #pragma warning(pop) to enable/disable them around specific headers (where #### is the warning you want to disable).
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

### #10NightCreature83  Members

4785
Like
1Likes
Like

Posted 15 December 2012 - 06:28 PM

Also, whack up your warning level to the highest possible (level 4 I think), and fix all of them. If you get warnings from 3rd party headers, you can use #pragma warning(push:####) and #pragma warning(pop) to enable/disable them around specific headers (where #### is the warning you want to disable).

In that case I would suggest you also set the flag treat warnings as errors, which forces you to fix them.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

### #11kubera  Members

1528
Like
0Likes
Like

Posted 15 December 2012 - 06:47 PM

Hi!

Visual C++ could show such warning, but the compiler must have set the correct warning level.

Why such strange comparision? Maybe you would construct a bit more complex if.
Such magic values, etc sometimes are unsafe and strange for reading.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.