Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > negative number evaluating greater than string.size()

Reply
Thread Tools

negative number evaluating greater than string.size()

 
 
lilburne
Guest
Posts: n/a
 
      02-20-2004
Rolf Magnus wrote:

> lilburne wrote:
>
>
>>>Of course this is what the OP should do, but notice that the solution
>>>effectively rules out strings where size() > INT_MAX. So why design
>>>for such strings in the first place? Why not have size() return an
>>>int?
>>>

>>
>>Because its more flexible to have a type where someone can
>>hold a string thats over 2Gb in size.

>
>
> I think it's not.



I think so too.


> You'd run into troubles if you need to calculate
> offsets between two characters in your string. That offset might be
> negative. Now you can't represent all possible offests anymore, no
> matter whether you make the type for that offset signed or unsigned.
> And further, if you mix signed and unsigned in your calculations, you
> have to be very careful.
>


I think it was for the reasons of inadvertantly mixing
signed and unsigned that Lakos recommended avoiding unsigned
in interfaces in "Large Scale C++".

 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      02-20-2004

"Andre Kostur" <(E-Mail Removed)> wrote in message
news:Xns94949E1E88AFEnntpspamkosturnet@207.35.177. 135...
> "John Harrison" <(E-Mail Removed)> wrote in

news:c13cvl$1dskq6$1
> @ID-196037.news.uni-berlin.de:
>
> >> What type should be used to hold the type of that operation?

> >
> > I meant
> >
> > What type should be used to hold the result of that operation?

>
> size_t, assuming the programmer has done the sane thing and checked that
> they are actually subtracting the smaller from the larger.


It gets very tedious after a while.

size_t size_a = ...;
size_t size_b = ...;
size diff;
bool a_is_bigger;
if (a > b)
{
diff = size_a - size_b;
a_is_bigger = true;
}
else
{
diff = size_b - size_a;
a_is_bigger = false;
}
process_diff(diff, a_is_bigger);

and hence its prone to errors, as we have all seen. In fact I very rarely
see code that takes this much trouble. It would be easier if size_t was
defined as a signed integer, and not a great deal would have been lost.

john



 
Reply With Quote
 
 
 
 
Andrey Tarasevich
Guest
Posts: n/a
 
      02-20-2004
John Harrison wrote:
> ...
> It would be easier if size_t was
> defined as a signed integer, and not a great deal would have been lost.
> ...


It wouldn't solve anything. It would just made the problem less obvious.
In general case the difference between two signed integers does not fit
into the range of the same signed integer type. The resultant signed
type must be at least one bit longer than original types.

--
Best regards,
Andrey Tarasevich

 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      02-20-2004

"Andrey Tarasevich" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> John Harrison wrote:
> > ...
> > It would be easier if size_t was
> > defined as a signed integer, and not a great deal would have been lost.
> > ...

>
> It wouldn't solve anything. It would just made the problem less obvious.
> In general case the difference between two signed integers does not fit
> into the range of the same signed integer type. The resultant signed
> type must be at least one bit longer than original types.
>


When that integer represents the size of something, it can only be positive
or zero. If it always possible to subtract two such positive signed numbers
without overflow. That's obvious isn't it?

john


 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      02-20-2004
John Harrison wrote:
>> > ...
>> > It would be easier if size_t was
>> > defined as a signed integer, and not a great deal would have been lost.
>> > ...

>>
>> It wouldn't solve anything. It would just made the problem less obvious.
>> In general case the difference between two signed integers does not fit
>> into the range of the same signed integer type. The resultant signed
>> type must be at least one bit longer than original types.
>>

>
> When that integer represents the size of something, it can only be positive
> or zero. If it always possible to subtract two such positive signed numbers
> without overflow. That's obvious isn't it?
> ...


Yes, but the trade-off in this case is that you can only use half of the
type's range.

--
Best regards,
Andrey Tarasevich

 
Reply With Quote
 
Jeff Schwab
Guest
Posts: n/a
 
      02-20-2004
John Harrison wrote:
> "Gianni Mariani" <(E-Mail Removed)> wrote in message
> news:c12sm0$(E-Mail Removed)...
>
>>Jason wrote:
>>
>>>Hi, below is example code which demonstrates a problem I have encountered. When passing a number to a function I compare it with a string's size and then take certain actions, unfortunately during the testing of it I discovered that negative numbers were being treated as if they were > 0. I compiled the following on mingw compiler/dev c++/windows xp. If I replace string.size() for a ordinary number it behaves as expected? I
>>>notice string.size() returns size type and not an int but how do I deal with that? Thanks in advance for any help


<reinserted>

void something(int number) {
if(number < str.size()) { /*...*/ }
}

</>

>>GCC sez:
>>
>>signed_probs.cpp: In function `void something(int)':
>>signed_probs.cpp:17: warning: comparison between signed and unsigned
>>integer expressions
>>
>>Changing line 17 to :
>>
>> if(number < static_cast<int>(str.size())) { cout << " hello" << endl; }
>>
>>solves the problem.
>>

>
>
> Of course this is what the OP should do,


No, an unnecessary cast is not what the OP should do. The problem is
that a signed "number" is being compared to an unsigned "size." "int"
and "string::size_type" are not the same thing; they are not always
comparable. A more reasonable solution would be for "number" to be of
string::size_type in the first place, or of a signed type that knows how
to compare itself with string::size_type.

 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      02-20-2004
lilburne wrote:

> I think it was for the reasons of inadvertantly mixing
> signed and unsigned that Lakos recommended avoiding unsigned
> in interfaces in "Large Scale C++".


Same for Stroustup in TC++PL. Strange enough that size_t is unsinged,
since Stroustrup probably had to do something with it. In the book, he
writes:

"The unsigned integer types are ideal for uses that treat storage as a
bit array. Using an unsigned instead of an int to gain one more bit to
represent positive integers is almost never a good idea. Attempts to
ensure that some values are positive by declaring variables unsigned
will typically be defeated by the implicit conversion rules."


 
Reply With Quote
 
lilburne
Guest
Posts: n/a
 
      02-20-2004


Jeff Schwab wrote:

>
> No, an unnecessary cast is not what the OP should do. The problem is
> that a signed "number" is being compared to an unsigned "size." "int"
> and "string::size_type" are not the same thing; they are not always
> comparable. A more reasonable solution would be for "number" to be of
> string::size_type in the first place, or of a signed type that knows how
> to compare itself with string::size_type.
>


Naturally! And std::vector::size_type, std::list::size_type,
std::deque::size_type, std::set::size_type, std::map::size_type, etc,
whenever dealing with the corresponding class. Maybe they'll all be the
same underlaying type, but who can tell?

 
Reply With Quote
 
Jeff Schwab
Guest
Posts: n/a
 
      02-20-2004
lilburne wrote:
>
>
> Jeff Schwab wrote:
>
>>
>> No, an unnecessary cast is not what the OP should do. The problem is
>> that a signed "number" is being compared to an unsigned "size." "int"
>> and "string::size_type" are not the same thing; they are not always
>> comparable. A more reasonable solution would be for "number" to be of
>> string::size_type in the first place, or of a signed type that knows
>> how to compare itself with string::size_type.
>>

>
> Naturally! And std::vector::size_type, std::list::size_type,
> std::deque::size_type, std::set::size_type, std::map::size_type, etc,
> whenever dealing with the corresponding class.


That's right.

> Maybe they'll all be the
> same underlaying type, but who can tell?


A specialized template can.

 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      02-20-2004
Andrey Tarasevich wrote:

> John Harrison wrote:
>>> ...
>>> Changing line 17 to :
>>>
>>> if(number < static_cast<int>(str.size())) { cout << " hello" <<
>>> endl; }
>>>
>>> solves the problem.
>>>

>>
>> Of course this is what the OP should do, but notice that the solution
>> effectively rules out strings where size() > INT_MAX. So why design
>> for such strings in the first place? Why not have size() return an
>> int? ...

>
> In my opinion, using a signed type to store an unsigned quantity is a
> low-level design error.


In mine, it's a design error to use an unsigned type if you don't have a
very good reason to do so. That you only want to store non-negative
values is not such a reason.
Why is there no unsigned floating point type, just for the case you want
to store only postive values?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
count the number of element in an array that are greater than somevalues? Peng Yu Perl Misc 3 06-19-2010 09:26 AM
Include header files in quotes or less-than greater-than signs? Dwight Army of Champions C++ 4 03-17-2010 06:39 PM
regex problem: 'greater than' 'less than' and 'equals' not matching! falcon Java 10 02-24-2006 01:23 PM
Random number if range is greater than RAND_MAX? Martin C++ 9 11-15-2004 01:43 PM
Negative setup and Negative hold prem_eda VHDL 5 10-11-2004 12:14 PM



Advertisments