Strange problem with size_t

G

Gaijinco

For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

What's wrong with that code? When I should definitely use size_t insted
of int?

Thanks.
 
I

Ian Collins

Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

Which is?
 
G

Gaijinco

It prints an infinte amount of character until it crashes but I
supposed the exact behavior must be machine and compiler-dependant so I
did'nt want to get into details.

What's wrong with using size_t?
 
I

Ian Collins

Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)

size_t is unsigned, so i>=0 will never fail if i is a size_t.
 
C

Clark S. Cox III

Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

What's wrong with that code? When I should definitely use size_t insted
of int?

Thanks.


size_t is unsigned, so it will never be less than zero; hence, the
expression (i>=0) is always true. Counting down with unsigned variables
can be tricky.

You could do something like:
....
const size_t size = s.size();
for(size_t i=size-1; i<size; --i)
{
....
 
K

Kai-Uwe Bux

Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.


size_t is an unsigned type. The idioms for counting down are therefore
different:

for(size_t i=s.size(); i-- > 0; )
{
n+=power*alpha.find(s);
power*=base;
}



Best

Kai-Uwe Bux
 
F

Frederick Gotham

Kai-Uwe Bux posted:
for(size_t i=s.size(); i-- > 0; )
{
n+=power*alpha.find(s);
power*=base;
}



My own personal favourite is:

for(size_t i = WHATEVER - 1; (size_t)-1 != i; --i)

(Cast is used to suppress compiler warning)

Or another one would be:

for(size_t i = WHATEVER -1; ~i; --i)

The latter example will break if integer promotion takes place (but I don't
think it should for a size_t).
 
K

Kai-Uwe Bux

Frederick said:
Kai-Uwe Bux posted:
for(size_t i=s.size(); i-- > 0; )
{
n+=power*alpha.find(s);
power*=base;
}



My own personal favourite is:

for(size_t i = WHATEVER - 1; (size_t)-1 != i; --i)

(Cast is used to suppress compiler warning)

Or another one would be:

for(size_t i = WHATEVER -1; ~i; --i)

The latter example will break if integer promotion takes place (but I
don't think it should for a size_t).


Maybe this is a good opportunity to point out a little detail in the code I
provided: the use of "i-- > 0" as opposed to "i-- != 0". I tend to prefer
reusable code. The version

for ( i = upper_bound; i-- > 0; ) {
some code;
}

will work for signed and unsigned types. Thus, I could even use it when the
type of i is given by a template parameter.


Best

Kai-Uwe Bux
 
P

Philip Potter

Kai-Uwe Bux said:
Maybe this is a good opportunity to point out a little detail in the code I
provided: the use of "i-- > 0" as opposed to "i-- != 0". I tend to prefer
reusable code. The version

for ( i = upper_bound; i-- > 0; ) {
some code;
}

will work for signed and unsigned types. Thus, I could even use it when the
type of i is given by a template parameter.

I don't see how "i-- != 0" fails to have this property. (Indeed, for
unsigned types it is exactly the same.)
 
K

Kai-Uwe Bux

Philip said:
I don't see how "i-- != 0" fails to have this property. (Indeed, for
unsigned types it is exactly the same.)

If upper_bound happens to be negative, the != 0 version enters an infinite
loop, whereas the > 0 version just does nothing.


Best

Kai-Uwe Bux
 
G

Greg Comeau

Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

Which is?


I'll wager a quick quess that the problem is in some case size yields 0
therfore size() - 1 is negative, but size_t is unsigned.
 
V

Victor Bazarov

Greg Comeau said:
Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

Which is?


I'll wager a quick quess that the problem is in some case size yields 0
therfore size() - 1 is negative, but size_t is unsigned.



"In some case"? In *all cases* the function is bound to run infinitely
if 'i' is 'size_t' because the condition in the 'for' statement (i>=0) is
simply always true (all unsigned values are greater than, or equal, zero).

V
 
I

Ian Collins

Greg said:
Ian Collins said:
Gaijinco said:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.


Which is?



I'll wager a quick quess that the problem is in some case size yields 0
therfore size() - 1 is negative, but size_t is unsigned.


I was prompting the OP the explain "behavies on a very unspected way".
Posters often make vague statements like "didn't work" where an exact
description would help to identify the problem.
 
G

Greg Comeau

Greg Comeau said:
Gaijinco wrote:
For some time now I have forced myself to use size_t instead of int
when I'm using a loop to go thru an array.

But today I found something odd:

long hex2long(const string& s)
{
string alpha="0123456789ABCDEF";
const long base=16;
long power=1, n=1;
for(int i=s.size()-1; i>=0; --i)
{
n+=power*alpha.find(s);
power*=base;
}
return n;
}

This works, but if I make the change the int for size_t, the program
behavies on a very unspected way.

Which is?


I'll wager a quick quess that the problem is in some case size yields 0
therfore size() - 1 is negative, but size_t is unsigned.


"In some case"? In *all cases* the function is bound to run infinitely
if 'i' is 'size_t' because the condition in the 'for' statement (i>=0) is
simply always true (all unsigned values are greater than, or equal, zero).


Indeed. I wasn't trying to say otherwise, but -- clearly poorly -- why
size_t is not always text replaceable for int.
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top