time to get rid of unsigned?

D

Dennis \(Icarus\)

John Harrison said:
Well I think I've covered that one already in another post.

Assignments are useful if dangerous, but of course some people do advocate
banning them on exactly those grounds, ask a functional programming zealot.

Unsigned integers are fairly useless, and somewhat dangerous, in my
opinion.

And yet, you found them useful
"I didn't say I don't have to do it, in fact writing a large integer
library is one thing I have done (and yes I did use unsigned
integers). I said its not something *many* people have to do."

Merely because you find unsigned to be fairly useless, doesn't make it so.
Especially since you did find 'em useful in at least one instance.
Could it be they're useful to other folks, too?
IIRC, you've said that
"Well I'm not being entirely serious, but this issue is a particular
bugbear of mine, and I thought the Windows source was a good
example to back it up. I don't expect to get much agreement.
(But one person agreeing with me would be nice). "

Found that one person, yet? (who agrees that unsigned should be removed? )

Dennis
 
L

lilburne

Dennis said:
Found that one person, yet? (who agrees that unsigned should be removed? )

From our coding standard:

"Avoid the use of unsigned int.
An unsigned argument may be passed a negative number and C++ will
silently convert it to a large positive value. Similarly if
arithmetic is performed on an unsigned value returned from a
function, the result may unexpectedly be a large positive value."

this is a direct reversal of an earlier policy to use unsigned where the
value would never be negative. The history of how the change came about
is a sorry litturgy of code breaking, exhibiting unintended behaviour,
causing abiguity problems.

So whilst we don't remove it all together, anyone that does use it must
"Be prepared to defend violations of recommendations."

now you might like to ponder why it is, if unsigned is so useful in the
public interface, that in <math> there is:

long abs(long x);

rather than:

unsigned long abs(long x);
 
J

Julie J.

abs is a math function.

signed integers should be used for the storage of values that are primarily
used in arithmetic situations.
 
N

Nick Hounsome

Julie J. said:
abs is a math function.

signed integers should be used for the storage of values that are primarily
used in arithmetic situations.

I see you've watered down your criteria from last time I replied to you but
my argument still stands:
They might not be PRIMARILY be used in arithmetic situations now but they
might in the future.
Consequently maintainability/enhancability requires that you do not use
unsigned in the interface.
Having dispensed with unsigned in the interface it is only asking for
trouble to use it in the implementation.

Furthermore, how much arithmetic do you have to do on an integer for it to
be PRIMARILY used in arithmetic
situations?
 
P

P.J. Plauger

Consequently maintainability/enhancability requires that you do not use
unsigned in the interface.
Having dispensed with unsigned in the interface it is only asking for
trouble to use it in the implementation.

Uh, no. We use unsigned arithmetic in the implementation of our libraries
all the time, to *avoid* trouble. With it we can model modulus arithmetic,
non-negative arithmetic, and twos complement arithmetic, all with no fear
of undefined behavior due to overflows. I'm inclined to agree that mixing
signed and unsigned arithmetic is error prone, and hence worth avoiding
in interfaces used by civilians. But don't tell us implementors not to
use the best tools we have for getting the job done properly.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
J

Julie J.

Unsigned *should* be used in the interface.

would you prefer

void * allocate(signed int block_size);

?

I greatly prefer

void * allocate(unsigned int block_size);

and it is much more self-documenting.
 
L

lilburne

P.J. Plauger said:
Uh, no. We use unsigned arithmetic in the implementation of our libraries
all the time, to *avoid* trouble. With it we can model modulus arithmetic,
non-negative arithmetic, and twos complement arithmetic, all with no fear
of undefined behavior due to overflows. I'm inclined to agree that mixing
signed and unsigned arithmetic is error prone, and hence worth avoiding
in interfaces used by civilians. But don't tell us implementors not to
use the best tools we have for getting the job done properly.

I think that the right approach. Isolating unsigned within
an implementation is fine. Its when it leaks into the public
interfaces that problems can and do occur.
 
D

Dennis \(Icarus\)

lilburne said:
From our coding standard:

"Avoid the use of unsigned int.
An unsigned argument may be passed a negative number and C++ will
silently convert it to a large positive value. Similarly if
arithmetic is performed on an unsigned value returned from a
function, the result may unexpectedly be a large positive value."

this is a direct reversal of an earlier policy to use unsigned where the
value would never be negative. The history of how the change came about
is a sorry litturgy of code breaking, exhibiting unintended behaviour,
causing abiguity problems.

So whilst we don't remove it all together, anyone that does use it must
"Be prepared to defend violations of recommendations."

So you choose not to use it. Fine & dandy.
Think it should be removed from the language?

Or would you just want to insure that unsigned can't be used as parameters?

Or do you find it useful in some circumstances, problematic if not used
carefully and, givne past history, you want to insure that proper care is
used?
now you might like to ponder why it is, if unsigned is so useful in the
public interface, that in <math> there is:

long abs(long x);

rather than:

unsigned long abs(long x);

Sure, and you can take a look at how size_t is defined.

:)

Dennis
 
A

Albert van der Horst

Your complaint, then, is about the fact that integers overflow. It has
nothing to do with whether the types involved are signed.

If you think that C/C++ unsigned integers can overflow, you have
a wrong conceptual view of them.
The correct view is
it is now 18:00 hours
7 hours later : 1:00 hours
23 hours earlier : 19:00 hours
25 hours later : 19:00 hours
The sign (P.M or A.M) is totally irrelevant, and, yes, you can
add or subtract any value you want, even if it doesn't fit in an
unsigned int.

If I were to make a c-compiler the following would trap
on implementation with 16 bits int's :
signed int i;
unsigned int u=0xFFFF;
i=u; /* Overflow trap! */

Nowadays you could add a (reinterpret_cast) to make at least the
intention clear.

While we are at it we could add traps for any bit-wise operations
on signed ints.

Head when the compiler says
WARNING: bitwise operation on signed values.

C is an unsafe language. Most warnings are actually errors.
#include <iostream>
#include <limits>

int main( )
{
signed s = std::numeric_limits< signed >::max( );

std::cout << s << " + 1 = " << ( s + 1 ) << " ?\n";
^^
Don't use bit operators on signed values.
You never need/want to do that.

Groetjes Albert
 
N

Nick Hounsome

Julie J. said:
Unsigned *should* be used in the interface.

would you prefer

void * allocate(signed int block_size);

?

I greatly prefer

void * allocate(unsigned int block_size);

and it is much more self-documenting.

If you are just going to say allocate(42) fine but what about allocate(s-10)
where s <10?

Do you prefer:

void* allocate(int size)
{
if( size < 0 ) throw domain_error("its negative stupid!");
...
}

or void* allocate(unsigned size)
{
// no way of checking
}

I'm only arguing your own point here - YOU said to use int when used in
arithmetic
expressions and you don't know when your clients are going to use arithmetic
expressions.
 
A

Albert van der Horst

unsigned integers are commonly used to declare 'count' or 'index' or 'size'*
type variables that will never contain negative values.

This is not correct use however. This usage is not in
correspondence with the conceptual meaning of unsigned. If you
have an array of length 10, do you then only use unsigned char
to index into the array? Unsigned is proper for circular
arithmetic, like a time stamp counter that goes on and on, and
for bit fields. Note that in algol 68 ``signed int'' is called
``int'' and ``unsigned int'' called ``bytes''. Then it comes as
a bit of a surprise that you could calculate somewhat with those
``bytes''. The naming of C makes only sense for people who
started their career in assembly programming, switching to a
high level language after three years.

It is an incidental consequence of the lowly ancestry of c++
that arrays cannot be like algol a[2000:2004] or
juliusyears[-41,23] .

If you want typing for your indices by all means do
typedef int INDEX_FOR_PATH_STRINGS;
and then have an ASSERT_IFPS() macro.
(If you want do it really well, you might consider switching to
ADA.)

Using unsigned for an index only serves the unintended purpose
of preventing any problems with negative values to be signaled.
An other poster has elaborated on this beautifully, stating
their new coding standards.
signed integers should be used for ingeger math*.

Shouldn't mix the types w/ the purpose, however it does happen. When writing
self-documenting code, you should use the type that applies.

Deprecating unsigned is essentially saying that the former reason has no
perceived value in the language.

The type ``bytes'' or in c-parlance ``unsigned int'' for
manipulating raw machine words is invaluable for those of us
writing compilers and other system programs. Those who are not,
should be careful with their comment. See also the comment of
Plauger.
(*other reasons exist, that are not delineated here.)

Hell no. The time has come for you to not use them, because you
have no business using them. Glad you discovered that. You are
not in writing compilers, assemblers, or high performance
bit-field codes, bignum packages.


--
 
A

Albert van der Horst

Thomas Matthews said:
My current escape goat on this topic is Borland.
They have used signed integers in their Windows
libraries where unsigned should be used (can a
control have a negative length?). So I am having
to perform casts on my code to be compatible with
their library.

Borland is right. You are wrong. See below.
If I writing an application for a {lung} ventilator,
and I need breaths per second, I cannot have a
negative quantity, so I will use an unsigned integer.
I don't want to have the risk of the controlling
variable to go into negative breaths per second.
Also, can one have a negative volume of air filled
into the lungs (can we say implosion?).

Do you really believe that where you make a program
error that results in negative breaths, your patient
is saved by using a type unsigned?
Warn me if you write such an application, so that
I can find an other hospital.
I also discussed that signed integers require at
least one bit for the sign, thus loosing one bit.

Big deal.
I'm working on an embedded system now that has
32 sources of interrupts. Not 31, but 32. So
we represent the register as an unsigned quantity
so we can access all 32 bits.
Appropriate use. The reason is that you look at the raw
bits here.
I belive that the signed and unsigned issue is one
of discipline. If one should drop unsigned integers
due to poor usage, then one should drop the entire
language because it can be very obscure without
discipline by programmers. Blame the programmers,
not the language. Does one fault a leaning house
on the tools or the developer?
I agree with this.
--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book


--
 
C

Claudio Puviani

Nick Hounsome said:
If you are just going to say allocate(42) fine but what about allocate(s-10)
where s <10?

If a programmer is stupid enough to write code like that, not only should he/she
be allowed to shoot him/herself in the foot, we should all pitch in to buy the
bullets. Anyone who can walk and chew gum at the same time will know that
calling allocate with a negative number is senseless and will test the
expression before calling the function. Programmers that don't start getting
that simple notion after a few days on the job need to be fired, not coddled.

Claudio Puviani
 
J

Julie J.

All I'm saying w/ unsigned is that the function is *not* going to check for
negative values. It is the callers responsibility to ensure that the input is
valid. So, if they send in -5 for a size (converted to unsigned 42-billion or
something), that is what would attempted to be allocated.

Now I realize that in this case there will probably be some arithmetic on the
input (such as quantity * block_size), but the primary intention of the
variable is to hold size-related information.

My comments have not intended to be 100% must-obey-rules, just guidelines for
the use of signed/unsigned integers.

Finally, my responses to the various postings on this topic have been merely to
illustrate that there are *multiple* disparate uses for integers. Not everyone
uses integers for math in the positive and negative domains.

I just wish people would take into account other's needs and experiences before
making such recommendations about removing language features, simply based on
'I don't have a need for it, so no one should...'.

The *entire* 'problem' surrounding unsigned/signed ints and math/conversion
overflow has to do with:

- no or a lack of coding standards
- no or insufficient code reviews
- no or insufficient unit testing
- no or insufficient documenation
- etc.

*not* because of language constructs.

The above items get a lot of lip service in the trade rags and books, but in
reality, how integrated are those items in everyday programming and
development? Definitely not as much as it should.

Later
 
N

Nick Hounsome

Claudio Puviani said:
If a programmer is stupid enough to write code like that, not only should he/she
be allowed to shoot him/herself in the foot, we should all pitch in to buy the
bullets. Anyone who can walk and chew gum at the same time will know that
calling allocate with a negative number is senseless and will test the
expression before calling the function. Programmers that don't start getting
that simple notion after a few days on the job need to be fired, not coddled.

Claudio Puviani

There are 3 places to check arguments to a function:
1. in the called function - 1 instance of the checking code exists
2. in the calling functions - this leads to unreadable code and enormous
code
bloat because a large number of instances of checking code exist many of
which may be wrong.

You seem to be advocating 2 over 1 - I think it is you that should be fired.

The only time you should normally validate arguments before calling a
function is when
dealing with user/externally supplied input. That is what runtime_error and
similar exceptions
exist for.

By your argument vector::at is unnecessary!
 
N

Nick Hounsome

Julie J. said:
All I'm saying w/ unsigned is that the function is *not* going to check for
negative values. It is the callers responsibility to ensure that the input is
valid. So, if they send in -5 for a size (converted to unsigned 42-billion or
something), that is what would attempted to be allocated.

I've covered this in another post. While I agree that the caller should try
to
be sensible the best place to check args in general is in the callee as the
alternative leads to unmaintainable code bloat here.
Now I realize that in this case there will probably be some arithmetic on the
input (such as quantity * block_size), but the primary intention of the
variable is to hold size-related information.

I do see what you mean but I insist that whatever the primary intention is,
the reality is tht it will frequently be called with an expression.
As for being self documenting that is just a red herring - if you leave out
unsigned can you come up with any plausible thought process by which
somebody is going to think it is ok to call a function called allocate with
a negative number?

The other problem with the self documenting argument is that you need
to read the documentation to know the arg is unsigned anyway.

Yet another argument against is that the compiler may well give you
a spurious warning for allocate(42) (passing signed to unsigned)
but will say nothing about a genuine problem: allocate((size_t)3-(size_t)42)
My comments have not intended to be 100% must-obey-rules, just guidelines for
the use of signed/unsigned integers.

I cannot accept them as guidelines because of the woolyness of the word
"primarily"
in your definition.
Finally, my responses to the various postings on this topic have been merely to
illustrate that there are *multiple* disparate uses for integers. Not everyone
uses integers for math in the positive and negative domains.

I just wish people would take into account other's needs and experiences before
making such recommendations about removing language features, simply based on
'I don't have a need for it, so no one should...'.

I have never seriously advocating removing or even not using unsigned except
as
formal parameters.
The *entire* 'problem' surrounding unsigned/signed ints and math/conversion
overflow has to do with:

- no or a lack of coding standards

Personally I think that there are too many coding standards and most are
written by people who know less than me.
- no or insufficient code reviews

That would go top of my list. Although I would tend to put this sort of
thing down as
nit-picking.
- no or insufficient unit testing
- no or insufficient documenation
- etc.

I couldn't agree more
 
C

Claudio Puviani

Nick Hounsome said:
There are 3 places to check arguments to a function:
1. in the called function - 1 instance of the checking code exists
2. in the calling functions - this leads to unreadable code and enormous
code
bloat because a large number of instances of checking code exist many of
which may be wrong.

You seem to be advocating 2 over 1 - I think it is you that should be fired.

The only time you should normally validate arguments before calling a
function is when
dealing with user/externally supplied input. That is what runtime_error and
similar exceptions
exist for.

You're missing a more fundamental point. The code in question (the one that
passes a negative value to an allocating function) should never have been
written in such a way that a negative value is possible. Testing for a
negative -- whether inside or outside the function -- is just a band-aid over a
design flaw that should never have been there. Defensive programming of the type
you advocate may be useful if you're dealing with beginners in C++, but it's
redundant (and unnecessarily expensive) when you're dealing with experienced
programmers.
By your argument vector::at is unnecessary!

It's completely unnecessary and a performance hurdle. vector::at is
sugar-coating for careless programmers. It could be removed and std::vector
would still be completely usable. Don't mistake convenience functions for
necessary ones.
 
A

Andre Kostur

There are 3 places to check arguments to a function:
1. in the called function - 1 instance of the checking code exists
2. in the calling functions - this leads to unreadable code and
enormous code
bloat because a large number of instances of checking code exist
many of which may be wrong.

There are 3 types of mathematicians in this world:
1) Those that can count
2) Those that can't.

:)
You seem to be advocating 2 over 1 - I think it is you that should be
fired.

I advocate the 3rd possibility that you left out:
3. At compile time (where possible, such as negative numbers to an
unsigned parameter).
 
C

Claudio Puviani

Andre Kostur said:
There are 3 types of mathematicians in this world:
1) Those that can count
2) Those that can't.

:)

Actually, there are 10 kinds of people in this world: those who can read binary
and those who can't. ;-)

Claudio Puviani
 

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,163
Messages
2,570,897
Members
47,435
Latest member
PhilipBelm

Latest Threads

Top