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
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
void something(int);
int main()
{
something(-1);
system("PAUSE");
return 0;
}
void something(int number) {
string str = "sdfjksdflksdjfkjsklfjsklfj";
if(number < str.size()) { cout << " hello" << endl; }
else { cout << " eek" << endl; }
} 25 2934
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
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.
"Jason" <ja***********@btinternet.com> wrote in message
news:c1**********@titan.btinternet.com... 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?
Suggest you read the recent thread 'time to get rid of unsigned?', started
on 17/02/04.
john
"Gianni Mariani" <gi*******@mariani.ws> wrote in message
news:c1********@dispatch.concentric.net... 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
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, 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?
john
John Harrison wrote: "Gianni Mariani" <gi*******@mariani.ws> wrote in message news:c1********@dispatch.concentric.net...
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, 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 remember something
like this being used as a justification for making size_t
unsigned some 15 years back, either in GCC documentation or
the "Standard C library", in relation to malloc().
Naturally someone will tell you that you should be coding
everything that deals with sizes and lengths with size_t.
"lilburne" <li******@godzilla.net> wrote in message
news:c1*************@ID-179504.news.uni-berlin.de... John Harrison wrote:
"Gianni Mariani" <gi*******@mariani.ws> wrote in message news:c1********@dispatch.concentric.net...
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, 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 remember something like this being used as a justification for making size_t unsigned some 15 years back, either in GCC documentation or the "Standard C library", in relation to malloc().
Interestingly the following code
int main()
{
std::string s;
std::cout << std::hex << s.max_size() << '\n';
}
when compiled with gcc 3.3.1 prints
3ffffffc
I don't think its a serious limitation to restrict yourself to strings which
occupy less than half of the available memory. Naturally someone will tell you that you should be coding everything that deals with sizes and lengths with size_t.
But what happens when you need to subtract one size from another? What type
should be used to hold the type of that operation? I don't think there is a
good answer.
john
> 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?
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. 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.
"John Harrison" <jo*************@hotmail.com> 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.
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. For this reason, in many practical applications
signed types in C/C++ are much less useful than unsigned types. And
'size()' must return an unsigned value.
As for correcting the OP's code, I would suggest doing it differently
if (number < 0 || (std::string::size_type) number < str.size())
{ cout << " hello" << endl; }
--
Best regards,
Andrey Tarasevich
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++".
"Andre Kostur" <nn******@kostur.net> wrote in message
news:Xn*******************************@207.35.177. 135... "John Harrison" <jo*************@hotmail.com> 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
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
"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:Ft********************@comcast.com... 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
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
John Harrison wrote: "Gianni Mariani" <gi*******@mariani.ws> wrote in message news:c1********@dispatch.concentric.net...
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.
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."
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?
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.
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?
Rolf Magnus wrote: ... 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.
Well, looks like we have different opinions on the subject.
Why is there no unsigned floating point type, just for the case you want to store only postive values?
For several reasons. It is much more difficult to provide
implementation-level support for an additional floating-point type than
for an additional integral type in situations when the underlying
hardware does not support it. Additionally, aside from purely conceptual
reasons, there is very little benefit from one extra mantissa (or
exponent) bit in a floating-point type. Under these circumstances, since
most hardware does not provide support for unsigned floating-point
types, it is not reasonable to force these types into language.
BTW, the reasons for domination of signed integral types in certain
arithmetical contexts in C (inherited into C++, like integral promotions
from smaller types) are probably very similar.
--
Best regards,
Andrey Tarasevich
> Suggest you read the recent thread 'time to get rid of unsigned?', started on 17/02/04.
john
I read all the whining about unsigned, and still disagree....
Regardless, what sense does it make to have a string with size < 0?
Furthermore, he should have been using
void something(std::string::size_type)
to start with.
In my mind, this is just a problem of people not reading the standard
documentation.
The least programmers should do is see the header files to understand
what types are being used, not just trust their instincts.
"Jorge Rivera" <jo*****@rochester.rr.com> wrote in message
news:1N*******************@twister.nyroc.rr.com... Suggest you read the recent thread 'time to get rid of unsigned?',
started on 17/02/04.
john
I read all the whining about unsigned, and still disagree....
Regardless, what sense does it make to have a string with size < 0?
That's not the point. Apparaently both Stroustrup and Lakos recomend
avoiding using unsigned for the size of something because of the potential
overflow problems, particularly (in my view) when one unsigned quantity has
to be subtracted from another.
Furthermore, he should have been using void something(std::string::size_type) to start with.
Maybe but you cannot know the problem he was working on. In my mind, this is just a problem of people not reading the standard documentation.
The least programmers should do is see the header files to understand what types are being used, not just trust their instincts.
Can't disagree with that.
john
Andrey Tarasevich <an**************@hotmail.com> wrote in message news:<10*************@news.supernews.com>... 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.
What does unsigned gain you? If you use signed and write code with a
bug, you could end up calculating someone's age as -1 years. If you
use unsigned and write the same code with the same bug you end up with
the age as 4294967295 years (assuming 32 bits as an example). Who
cares that one of those numbers happens to be >0? They are both as
wrong as the other. The code needs to be fixed whether age is signed
or unsigned, and once it is fixed, it will work whether age is signed
or unsigned.
--
GJD
Jorge Rivera <jo*****@rochester.rr.com> wrote in message news:<1N*******************@twister.nyroc.rr.com>. .. Suggest you read the recent thread 'time to get rid of unsigned?', started on 17/02/04.
john
I read all the whining about unsigned, and still disagree....
Regardless, what sense does it make to have a string with size < 0?
You missed the point. With a signed string size type, any code that
ends up with a size < 0 has a bug. If that same code had been written
with an unsigned string size type, it would still have a bug. The
garbage size value would now happen to be > 0, but so what? That
doesn't make the code any more correct. It is the same bug,
manifesting itself in a different way.
--
GJD
Furthermore, he should have been using void something(std::string::size_type) to start with.
In my mind, this is just a problem of people not reading the standard documentation.
The least programmers should do is see the header files to understand what types are being used, not just trust their instincts.
> You missed the point. With a signed string size type, any code that ends up with a size < 0 has a bug. If that same code had been written with an unsigned string size type, it would still have a bug. The garbage size value would now happen to be > 0, but so what? That doesn't make the code any more correct. It is the same bug, manifesting itself in a different way.
The point is simple, read the documentation, read the correct behavior
of std::string, use it appropriately.
std::string::size_type std::string::size()
can not return a negative number. If anything, functions within
std::string will return std::string::npos, and I doubt there is any
situtation in which std::size() would return it.
Any other assumptions about values returned by string are just that,
assumptions. The behavior of the class is what it is, and we all should
just play by its rules, not whine weahter the implementation is signed
or unsigned.
JLR This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Tripp Knightly |
last post by:
I have a lookup table from which I want to categorize various bands of
customer net income. Some of the income is positive, some is
negative. The bands vary in size (ie, <500, -200 to 0, 100 to...
|
by: John |
last post by:
Hi,
I encountered a strange problem while debugging C code for a
Windows-based application in LabWindows CVI V5.5, which led me to
write the test code below. I tried this code with a different...
|
by: Davey |
last post by:
How do I display an integer in binary format in C?
e.g. 4 displayed as "100"
|
by: tlyczko |
last post by:
Hello Rob B posted this wonderful code in another thread,
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/c84d8538025980dd/6ead9d5e61be85f0#6ead9d5e61be85f0
I could not...
|
by: andreas.lydersen |
last post by:
Hi!
While communicating with a monitoring unit, I get some hex values
representing degrees celcius from its probes. The values can be
something like '19' or '7d'. To convert it to int, I do the...
|
by: drtimhill |
last post by:
I'm just starting out on Python, and am stumped by what appears an oddity in the way negative indices are handled.
For example, to get the last character in a string, I can enter "x". To get the...
|
by: Frederick Gotham |
last post by:
I have a general idea about how negative number systems work, but I'd
appreciate some clarification if anyone would be willing to help me.
Let's assume we're working with an 8-Bit signed integer,...
|
by: hello2008 |
last post by:
Hi,
I donot have much knowledge of R.Exp. In my web page I am required to validate numeric textboxes allowing signed/unsigned integer/float numbers and then compare between them. I need the...
|
by: shashi shekhar singh |
last post by:
Respected Sir,
I am facing problem when i try to deploy my website on iis 7.0 on test page.
i have to display some .mht files on iframe in gridview and error looks like below,
Server Error in...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
| |