why always out_of_range using size_type?

F

Frederick Ding

Hi,guys!
Please look at this problem, when I use "int i", it success, but when I
use string::size_type i, it fail with a out_of_range exception.
//---------------- begin----------------------------

int str_to_num(const string& s)
{
int num = 0;
int interval = 1;
int i; // success
//string::size_type i; //always cause a out_of_range exception

for (i = s.length() - 1; i >= 0; --i) {
num += static_cast<int>(s.at(i) - 'a' + 1) * interval;
interval *= 26;
}

return num;
}





//-----------------end------------------------------
//a b c .... z aa ab ac .... az ba bb bc .... yz za zb zc .... zz aaa aab
aac ..
//.. change these string to number:
//1 2 3 .... 26 27 28 29 .... 52 53 54 55 .... 676 677 678 679 .... 702 703
704
//705 ....

IDE/Compiler: Borland C++ Builder 6

I know that the string::at() function cause this out_of_range exception, but
why size_type cause this?

Any help is appreciated, thanks!


--
 
O

Oliver Kreylos

Frederick said:
Hi,guys!
Please look at this problem, when I use "int i", it success, but when I
use string::size_type i, it fail with a out_of_range exception.
//---------------- begin----------------------------

int str_to_num(const string& s)
{
int num = 0;
int interval = 1;
int i; // success
//string::size_type i; //always cause a out_of_range exception

for (i = s.length() - 1; i >= 0; --i) {
num += static_cast<int>(s.at(i) - 'a' + 1) * interval;
interval *= 26;
}

return num;
}

I guess that size_type is an unsigned type. Values of unsigned types can
never be smaller than zero, so the condition in the for loop is always
true, and the index runs out of bounds. Concrete: if i is zero at one
point, you do another loop, which decrements i. Since i is unsigned, it
wraps around to some large positive number, which is most probably out
of range.

General rule: Be careful when comparing for >= 0, and never do it for
unsigned types.

Oliver
 
J

Jonathan Mcdougall

Please look at this problem, when I use "int i", it success, but
when I
use string::size_type i, it fail with a out_of_range exception.

string::size_type is usually an unsigned integer.
int i; // success
//string::size_type i; //always cause a out_of_range exception
for (i = s.length() - 1; i >= 0; --i) {

If 'i' is unsigned, this will always be true. When 'i' is 0 and you
decrement it, it becomes the largest integer that may be represented.

Jonathan
 
R

Rade

If 'i' is unsigned, this will always be true. When 'i' is 0 and you
decrement it, it becomes the largest integer that may be represented.

The bottom line: raise the warning level of your compiler to the highest
possible, and then review the warnings. If you do that, you will probably
find a warning that the "condition is always true"...

It is never a good thing to leave unexplained warnings in your code, or to
lower the warning level to get rid of them. Treat warnings as errors unless
there is a good reason not to do so.

Rade
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top