Topic: promotion - signed --> unsigned


Author: yngvar.folling@login.eunet.no (Yngvar Folling)
Date: 1997/10/02
Raw View
In article <vyzwwk0migk.fsf@issan.informatik.uni-dortmund.de>,
Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> wrote:
> Yngvar Folling <yngvar.folling@login.eunet.no> writes:
>
> |> Maybe a bit tangential to the problem, but if you want to sort using the
> |> standard "qsort" function, and you "know" that a uid is a nonnegative
> |> integer, one may assume that it is safe for the comparison function to
> |> return the result of a simple subtraction of the two indexes.
>
> This is never safe, not due to signed/unsigned, but due to size (int may
> be too small to represent the difference of two uid_t values, and surely
> is if uid_t is unsigned int).

As I said: If a uid is a nonnegative *integer*.  That is, if it is
guaranteed to be within the range 0 to INT_MAX.  I understood an earlier
post in this thread as if this was guaranteed at some point, but was
changed later.  If you relied on that, the subtraction could be relied
on to yield a result in the range -INT_MAX (which is equal to or one
more than INT_MIN) to INT_MAX, which fits in an integer.

Of course, as soon as we no longer have that guarantee, it breaks, no
matter if the type changes to unsigned, or long, or unsigned long.  Or
even unsigned short, if short and int have the same size.

Yngvar
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/10/02
Raw View
Yngvar Folling wrote:
...
> As I said: If a uid is a nonnegative *integer*.  That is, if it is
> guaranteed to be within the range 0 to INT_MAX.  I understood an earlier
...

In C, the word 'integer' can be ambiguous. In some contexts it can be
used to refer to any integral type. It is safer to be more specific and
say 'int', if that is what you mean.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: 1997/09/29
Raw View
Yngvar Folling <yngvar.folling@login.eunet.no> writes:

|> Maybe a bit tangential to the problem, but if you want to sort using the
|> standard "qsort" function, and you "know" that a uid is a nonnegative
|> integer, one may assume that it is safe for the comparison function to
|> return the result of a simple subtraction of the two indexes.

This is never safe, not due to signed/unsigned, but due to size (int may
be too small to represent the difference of two uid_t values, and surely
is if uid_t is unsigned int).

--
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: yngvar.folling@login.eunet.no (Yngvar Folling)
Date: 1997/09/25
Raw View
In article <vyz202linjg.fsf@issan.informatik.uni-dortmund.de>,
schwab@issan.informatik.uni-dortmund.de (Andreas Schwab) wrote:
> Michael Viking <nospam@techne-sys.com> writes:
>
> |> Bigger could mean plenty in the context of user ids in that perhaps I'd
> |> like to sort my users by ID number.  In that case, it would make a lot
> |> of sense for me to be able to have < and > defined for user ids.
>
> You can already do that now.  There is no problem in comparing values of
> exactly the same type, where the semantics are all unchanged between K&R
> and ANSI.  The only difficuties aries when you try to compare values of
> different types, but that doesn't arise during sorting.

Maybe a bit tangential to the problem, but if you want to sort using the
standard "qsort" function, and you "know" that a uid is a nonnegative
integer, one may assume that it is safe for the comparison function to
return the result of a simple subtraction of the two indexes.  If the
type of a uid is then changed to an unsigned, that may break, and the
subtraction has to be replaced with a series of "if" statements.

Yngvar
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: schwab@issan.informatik.uni-dortmund.de (Andreas Schwab)
Date: 1997/09/19
Raw View
Michael Viking <nospam@techne-sys.com> writes:

|> Bigger could mean plenty in the context of user ids in that perhaps I'd
|> like to sort my users by ID number.  In that case, it would make a lot
|> of sense for me to be able to have < and > defined for user ids.

You can already do that now.  There is no problem in comparing values of
exactly the same type, where the semantics are all unchanged between K&R
and ANSI.  The only difficuties aries when you try to compare values of
different types, but that doesn't arise during sorting.
--
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/09/23
Raw View
Michael Viking <nospam@techne-sys.com> writes:

> Bigger could mean plenty in the context of user ids in that perhaps I'd
> like to sort my users by ID number.  In that case, it would make a lot
> of sense for me to be able to have < and > defined for user ids.
>
> Andreas Schwab wrote:
> >
> > Chris Torek <torek@elf.bsdi.com> writes:
> >
> snip
> >
> > IMHO it most often does not make sense to compare such a value with < or >
> > (as opposed to =).  For example, what does `bigger' mean in the context of
> > user ids?

In C++, a way to do that in general is less<anything>. If uid_t was
a class type, I'd define less on it but not <.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: meem <meem@park28.wuh.wustl.edu>
Date: 1997/09/14
Raw View
Per Erik Stendahl <berrs@hotmail.com> writes:

> Scott Mayo wrote:
> > In comp.std.c,comp.std.c++, Per Erik Stendahl <berrs@hotmail.com> wrote:
> > <What are the arguments for this behaviour?
> > The original argument was probably that I + U should yield U,
> > because, well, probably because it was easier, and less prone
> > to overflow. And if I op U yields a U, and < is an op... you
> > can see how it started.
>
> Aye, we are slaves to yesterdays compromises. I wonder what "they"
> thought about U - <whatever-signed>? Would that also yield a U,
> even there's big potential for a negative number?

if you want to know what "they" thought, why don't you read the part
of the standard that describes these promotions.  it's not as complex
as you're making it out to be.  it's also summarized in K&R.

> > Don't even try it. There's code out there that *knows* that ints
> > will be cast to unsigned when it meet an unsigned value across
> > an operator, and this will break it. Granted such code deserves to
> > suffer, but it won't happen.
>
>
> Oh, I know about that code. But new features are constantly introduced
> and sometimes old ones removed.

you're right.  but in fact, this is a relatively `new' feature -- it
wasn't standardized until ANSI C -- before then, many compilers took
the "more intuitive approach".

--
:: meem@park28.wuh.wustl.edu  :: voice 314/935-1667  :: pager 800/652-2699  ::
::   pgp fingerprint:   E7 E8 1A 95 F2 06 6A D6   6A 11 44 D6 6A 6B 93 9B   ::
:: GCS v3.12: a-- C+++ UL++++ US++++ UB+++ P++ L+++>++++++ E+>+++ W+ N++ K+ ::
::            w+ O@ M- V- PS+ Y+ PGP++ t+ 5 X R- tv- b DI++ D+ G h+ r- z-   ::
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Tan Wee Yeh <tanweeye@iscs.nus.edu.sg>
Date: 1997/09/14
Raw View
In comp.std.c Richard A. O'Keefe <ok@cs.rmit.edu.au> wrote:
: Comparing signed with unsigned integers:

: int su_cmp(signed long x, unsigned long y) {
:     unsigned long u;

:     if (x < 0) return -1;
:     u = x;
:     return (u > y) - (u < y);
: }

I believe most machines implements integers as binary
numbers and negatives in 2's complement.  In that case
isn't (num)L = (num)UL if num > 0?

Given that, we can actually save the assignment of
u = x (corresponding the (unsigned long) typecast).

Please comment.


--
Just me,
Wire ...
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: torek@elf.bsdi.com (Chris Torek)
Date: 1997/09/15
Raw View
In article <5vbsuq$rka@nfs0.sdrc.com> <larry.jones@sdrc.com> wrote:
>... In most pre-ANSI implementations, any unsigned operand of any
>size caused the result to also be unsigned.  This was later dubbed
>"unsignededness preserving rules" as opposed to the "value preserving
>rules" that ANSI ultimately adopted.  For what it's worth, that was, in
>my opinion, the single most controversial decision the ANSI committee
>made -- to this day there are those who argue that the other rules are
>better.

Indeed.  An excerpt from my article <5ml7b7$nca@solutions.solon.com>
(edited a bit for clarity and/or mistakes :-) ):

... in which the result of widening any narrow unsigned type was
`unsigned int'.  In ANSI C, it is either int or unsigned int,
depending on the implmentation.  For instance:

 unsigned short s = ~(unsigned)0;
 int i; ...
 if (i < s)

In pre-ANSI C (e.g., under the old VAX PCC compiler), this always
meant the same as:

 if ((unsigned int)i < (unsigned int)USHRT_MAX)

In ANSI C, it sometimes means:

 if ((unsigned int)i < (unsigned int)USHRT_MAX)

but sometimes it means:

 if ((signed int)i < (signed int)USHRT_MAX)

Which of these occurs depends on the relative sizes of short and int.
If short is shorter than int, it means the latter; if short is the
same length as int, it means the former.

Thus:

 unsigned short s = USHRT_MAX;
 int i = -1;

 if (i < s) /* eg, -1 < 65535 */
  printf("ANSI C, and sizeof(int) > sizeof(short)\n");
 else  /* eg, 0xffffU == 0xffffU or 0xffffffffU > 0xffffU */
  printf("pre-ANSI C, or sizeof(int) == sizeof(short)\n");

Either output can occur under a conforming ANSI C system.  This
is why the choice that was made for ANSI C is wrong.  The correct
choice, `unsigned preserving' semantics, does not depend on the
relative sizes of short and int, and will always do an unsigned
comparison, so that we always test UINT_MAX >= USHRT_MAX, and the
second printf fires.  But Plauger insisted on the broken `value
preserving' semantics, arguing that it more often did what most
programmers expected.  The problem with this argument is that it
only does what these programmers expect when sizeof(int) >
sizeof(short) -- when the sizes are the same, it acts like pre-ANSI
C, so programmers cannot assume a signed comparison will occur.
It would be better always to do an unsigned comparison, giving a
fixed answer, rather than an implementation-specific answer.

As the Rationale points out, however, any difference in actual
behavior occurs only rarely.  Since the Rationale is missing from
the ISO edition, I quote:

 In [most] implementations, differences between [the
 result in an unsigned-preserving system and a value-
 preserving system] only appear when these two conditions
 are both true:

  1. An expression involving an |unsigned char| or
     |unsigned short| produces an |int|-wide result in
     which the sign bit is set: i.e., either a unary
     operation on such a type, or a binary operation in
     which the other operand is an |int| or ``narrower''
     type.

  2. The result of the preceding expression is used in
     a context in which its signedness is significant:

  o  |sizeof(int) < sizeof(long)| and it is in a
     context where it must be widened to a long
     type, or

  o  It is the left operand of the right-shift
     operator (in an implementation where this
     shift is defined as arithmetic), or

  o  It is either operand of /, %, <, <=, >, or >=.

 In such circumstances a genuine ambiguity of interpretation
 arises.  The result must be dubbed /questionably signed/ ....
 Of course, /all of these ambiguities can be avoided by a
 judicious use of casts./

[emphasis theirs]

This glosses over the difficulty of obtaining the correct cast when
the type in question is obtained via a typedef from a header whose
contents are not supposed to be examined, and/or which varies from
one system to the next.  (Consider, e.g., `uid_t' from some POSIX
header.  Is it signed?  What are the signed and unsigned variants
of this type?  Do they vary from one system to the next?  [The answer
to the last is a definite "yes".])
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA Domain: torek@bsdi.com +1 510 234 3167
Antispam notice: unsolicited commercial email will be handled at my
consulting rate; pyramid-scheme mail will be forwarded to the FTC.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ok@cs.rmit.edu.au (Richard A. O'Keefe)
Date: 1997/09/15
Raw View
I wrote:
: int su_cmp(signed long x, unsigned long y) {
:     unsigned long u;
:
:     if (x < 0) return -1;
:     u = x;
:     return (u > y) - (u < y);
: }

Tan Wee Yeh <tanweeye@iscs.nus.edu.sg> writes:
>I believe most machines implements integers as binary
>numbers and negatives in 2's complement.  In that case
>isn't (num)L = (num)UL if num > 0?

It doesn't matter.  The functions I posted only convert non-negative
signed integers to unsigned, and the C standard guarantees that the
representation of N (>= 0) as a signed integer is the same as the
representation of N as an unsigned integer of the same size.  So it
doesn't matter which of the three representations allowed by the C
standard (twos complement, ones complement, sign-and-magnitude) is
used, in all of them, u and x will have the same bits.

>Given that, we can actually save the assignment of
>u = x (corresponding the (unsigned long) typecast).

>Please comment.

What's to save?  This is the dynamically-last reference to x, so it's
dead after the assignment.  This is the dynamically-first assignment
to u.  I would expect a good compiler to use the same register for x
and u and to generate no code for that assignment statement.

However, the assignment statement _is_ needed.  The C checkers available
to me warn if you mix signed and unsigned in a comparison, so I want an
unsigned variable to use in the 'return' statement.  I have a value in a
signed variable, I want it in an unsigned variable, so an assignment is
appropriate even if I expect it to need no instructions at run time.

(If the compiler _does_ allocate different locations for x and u, and
_does_ generate code for that assignment, then it's probably going to
generate pretty poor code for other things too, including that 'return'
statement.  So the cost of the assignment really isn't worth worrying
about.)
--
Unsolicited commercial E-mail to this account is prohibited; see section 76E
of the Commonwealth Crimes Act 1914 as amended by the Crimes Legislation
Amendment Act No 108 of 1989.  Maximum penalty:  10 years in gaol.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: schwab@issan.informatik.uni-dortmund.de (Andreas Schwab)
Date: 1997/09/15
Raw View
Chris Torek <torek@elf.bsdi.com> writes:

|> This glosses over the difficulty of obtaining the correct cast when
|> the type in question is obtained via a typedef from a header whose
|> contents are not supposed to be examined, and/or which varies from
|> one system to the next.  (Consider, e.g., `uid_t' from some POSIX
|> header.  Is it signed?  What are the signed and unsigned variants
|> of this type?  Do they vary from one system to the next?  [The answer
|> to the last is a definite "yes".])

IMHO it most often does not make sense to compare such a value with < or >
(as opposed to =).  For example, what does `bigger' mean in the context of
user ids?
--
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ok@cs.rmit.edu.au (Richard A. O'Keefe)
Date: 1997/09/16
Raw View
[Chris Torek gave the example of uid_t]

schwab@issan.informatik.uni-dortmund.de (Andreas Schwab) writes:

>IMHO it most often does not make sense to compare such a value with < or >
>(as opposed to =).  For example, what does `bigger' mean in the context of
>user ids?

According to the POSIX standard, user IDs are positive.  There are no
standard values to compare with.  On the system I use, uid_t has changed
both size and signedness (in both directions) over the years.

_Bigger_ doesn't make sense, but _sorting_ does.  If you have a collection
of user IDs, and want to form it into a set that can be manipulated,
sorting is your best bet.  And since the POSIX standard _does_ say that
user IDs are positive, someone might well want to overlay some special
meaning onto (uid_t)(-1), just as waitpid() does with pid_t's.

I think we would have been better served had C89 ruled that comparisons
mixing signed and unsigned numbers were out-and-out illegal, so that
things like
 uid_t u; ... u > -1
would either work (if uid_t was signed) or produce a diagnostic (if uid_t
was unsigned).  However, it was not so.  Thank Evans for LClint!
--
Unsolicited commercial E-mail to this account is prohibited; see section 76E
of the Commonwealth Crimes Act 1914 as amended by the Crimes Legislation
Amendment Act No 108 of 1989.  Maximum penalty:  10 years in gaol.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: schwab@issan.informatik.uni-dortmund.de (Andreas Schwab)
Date: 1997/09/18
Raw View
Richard A O'Keefe <ok@cs.rmit.edu.au> writes:

|> [Chris Torek gave the example of uid_t]
|> schwab@issan.informatik.uni-dortmund.de (Andreas Schwab) writes:

|>> IMHO it most often does not make sense to compare such a value with < or >
|>> (as opposed to =).  For example, what does `bigger' mean in the context of
|>> user ids?

|> According to the POSIX standard, user IDs are positive.  There are no
|> standard values to compare with.  On the system I use, uid_t has changed
|> both size and signedness (in both directions) over the years.

|> _Bigger_ doesn't make sense, but _sorting_ does.

You will get the same result, whether you are using the unsigned or value
preserving rule, as long as you always only compare values with exactly the
same type.

|> I think we would have been better served had C89 ruled that comparisons
|> mixing signed and unsigned numbers were out-and-out illegal, so that
|> things like
|>  uid_t u; ... u > -1

If you compare two values of different types all bets are off.  Use ((uid_t)-1).
--
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Michael Viking <nospam@techne-sys.com>
Date: 1997/09/18
Raw View
Bigger could mean plenty in the context of user ids in that perhaps I'd
like to sort my users by ID number.  In that case, it would make a lot
of sense for me to be able to have < and > defined for user ids.

Andreas Schwab wrote:
>
> Chris Torek <torek@elf.bsdi.com> writes:
>
snip
>
> IMHO it most often does not make sense to compare such a value with < or >
> (as opposed to =).  For example, what does `bigger' mean in the context of
> user ids?
> --
> Andreas Schwab                                      "And now for something
> schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/09/10
Raw View
Per Erik Stendahl wrote:
>
> Hi.
>
> I noticed the following --- rather annoying --- behaviour with
> gcc 2.7.2:
>
>  -1 < 1   but  -1 > 1U
>
> So when in a comparison between a signed int and an unsigned int
> the signed int is promoted to an unsigned int with less than
> satisfactory results. Is this correct behaviour w r t the standard?
>

Yes.

> What are the arguments for this behaviour? If the unsigned int is less
> than 0x8000 (or whatever) then the comparison can be done "signedely",
> and if the unsigned int is larger, then it is definitly greater.
> "Only minor overhead" :)

Experience shows that valid comparisons between unsigned and signed
values usually involve signed values which are guaranteed, one way or
another, to be positive. In those cases, your 'minor' overhead buys no
advantage, at a cost that might be significant for some applications.
Avoiding that overhead would require an explicit cast of the signed type
to an unsigned type.

You can get the behavior you want within the current Standard by
explicitly casting the unsigned value to a signed type of sufficient
size to hold the largest value you will be working with. Requiring an
explicit cast for the less frequently required behaviour makes sense to
me.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jason Merrill <jason@cygnus.com>
Date: 1997/09/11
Raw View
>>>>> Per Erik Stendahl <berrs@hotmail.com> writes:

> I noticed the following --- rather annoying --- behaviour with
> gcc 2.7.2:

>  -1 < 1   but  -1 > 1U

2.8.0 (and EGCS, http://www.cygnus.com/egcs) will warn about that with
the -Wsign-compare flag.

Jason
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: smayo@ziplink.net (Scott Mayo)
Date: 1997/09/11
Raw View
In comp.std.c,comp.std.c++, Per Erik Stendahl <berrs@hotmail.com> wrote:

<Hi. I noticed the following --- rather annoying --- behaviour with
<gcc:

< -1 < 1   but  -1 > 1U

<So when in a comparison between a signed int and an unsigned int
<the signed int is promoted to an unsigned int with less than
<satisfactory results. Is this correct behaviour w r t the standard?

Sadly, yes.

<What are the arguments for this behaviour?

I can only assume a painful obedience to ancient history. It's
certainly insane to argue that a negative number is anything
other than strictly less than an unsigned anything. But C has
done it this way as long as I can remember. You have to either
cast the unsigned int down to int, if that's safe, or expand
your test. ( i < 0 || (unsigned)i < u ) is probably safe.

The original argument was probably that I + U should yield U,
because, well, probably because it was easier, and less prone
to overflow. And if I op U yields a U, and < is an op... you
can see how it started.

<If the unsigned int is less
<than 0x8000 (or whatever) then the comparison can be done "signedely",
<and if the unsigned int is larger, then it is definitly greater.
<"Only minor overhead" :)

Don't even try it. There's code out there that *knows* that ints
will be cast to unsigned when it meet an unsigned value across
an operator, and this will break it. Granted such code deserves to
suffer, but it won't happen.

Humane compilers warn you when this sort of thing occurs.

<It would be very nice to have some means of telling the compiler
<that the unsigned variable will *never* rise above some specified
<value. Some sort of pre-/postcondition perhaps. assert() doesn't
<really suffice IMHO.

Gee. Ranged ints. This sounds somewhat familiar.

One faintly helpful suggestion: code that mixes unsigned int and int
is typically being a little sloppy to start. If a quantity is
really unsigned, then the operations on it should really all be
unsigned. But that sort of code purity is rare, and sometimes not
possible.

--
"if unsigned, meets a sign'ed, comin' on the sly..."
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Per Erik Stendahl <berrs@hotmail.com>
Date: 1997/09/12
Raw View
Scott Mayo wrote:
> In comp.std.c,comp.std.c++, Per Erik Stendahl <berrs@hotmail.com> wrote:
> <What are the arguments for this behaviour?
> The original argument was probably that I + U should yield U,
> because, well, probably because it was easier, and less prone
> to overflow. And if I op U yields a U, and < is an op... you
> can see how it started.

Aye, we are slaves to yesterdays compromises. I wonder what "they"
thought about U - <whatever-signed>? Would that also yield a U,
even there's big potential for a negative number?

> <If the unsigned int is less
> <than 0x8000 (or whatever) then the comparison can be done "signedely",
> <and if the unsigned int is larger, then it is definitly greater.
> <"Only minor overhead" :)
>
> Don't even try it. There's code out there that *knows* that ints
> will be cast to unsigned when it meet an unsigned value across
> an operator, and this will break it. Granted such code deserves to
> suffer, but it won't happen.

Oh, I know about that code. But new features are constantly introduced
and sometimes old ones removed. I saw that gcc 2.8 (so it finally
arrived?) has a switch. That is good.

> <It would be very nice to have some means of telling the compiler
> <that the unsigned variable will *never* rise above some specified
> <value. Some sort of pre-/postcondition perhaps. assert() doesn't
> <really suffice IMHO.
>
> Gee. Ranged ints. This sounds somewhat familiar.

Yes, old concept. But is it such a bad idea then? I don't have any
experience using such things but I think it would improve readability
(declarative coding) and help debugging (by generating compile-time
errors/warnings).

> One faintly helpful suggestion: code that mixes unsigned int and int
> is typically being a little sloppy to start. If a quantity is
> really unsigned, then the operations on it should really all be
> unsigned. But that sort of code purity is rare, and sometimes not
> possible.

Well.. I was actually trying to avoid sloppyness. :) In my program most
variables never go negative, so I thought it might be a good idea to
use unsigneds and hope that the compiler catches eventual mistakes.
Maybe that was my biggest mistake! Back to school... :)

Cheers
Per Erik Stendahl
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ok@cs.rmit.edu.au (Richard A. O'Keefe)
Date: 1997/09/12
Raw View
Comparing signed with unsigned integers:

int su_cmp(signed long x, unsigned long y) {
    unsigned long u;

    if (x < 0) return -1;
    u = x;
    return (u > y) - (u < y);
}

int us_cmp(unsigned long x, signed long y) {
    unsigned long u;

    if (y < 0) return 1;
    u = y;
    return (x > u) - (x < u);
}

So anyone who wants e < f or the like where one of the expressions
is signed and the other unsigned can already get the effect they want
in the language, just rewrite it as
 su_cmp(e, f) < 0 if e is signed
 us_cmp(e, f) < 0 if f is signed

As for me, I will continue to ask my compilers to warn me whenever I
compare a signed quantity with an unsigned one without a cast to say
exactly what I mean.

--
Unsolicited commercial E-mail to this account is prohibited; see section 76E
of the Commonwealth Crimes Act 1914 as amended by the Crimes Legislation
Amendment Act No 108 of 1989.  Maximum penalty:  10 years in gaol.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: larry.jones@sdrc.com
Date: 1997/09/14
Raw View
In article <34181CE5.F5E@hotmail.com>, Per Erik Stendahl <berrs@hotmail.com> writes:
> Aye, we are slaves to yesterdays compromises. I wonder what "they"
> thought about U - <whatever-signed>? Would that also yield a U,
> even there's big potential for a negative number?

Yep.  In most pre-ANSI implementations, any unsigned operand of any
size caused the result to also be unsigned.  This was later dubbed
"unsignededness preserving rules" as opposed to the "value preserving
rules" that ANSI ultimately adopted.  For what it's worth, that was, in
my opinion, the single most controversial decision the ANSI committee
made -- to this day there are those who argue that the other rules are
better.

-Larry Jones

Archaeologists have the most mind-numbing job on the planet. -- Calvin
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Per Erik Stendahl <berrs@hotmail.com>
Date: 1997/09/10
Raw View
Hi.

I noticed the following --- rather annoying --- behaviour with
gcc 2.7.2:

 -1 < 1   but  -1 > 1U

So when in a comparison between a signed int and an unsigned int
the signed int is promoted to an unsigned int with less than
satisfactory results. Is this correct behaviour w r t the standard?

What are the arguments for this behaviour? If the unsigned int is less
than 0x8000 (or whatever) then the comparison can be done "signedely",
and if the unsigned int is larger, then it is definitly greater.
"Only minor overhead" :)

It would be very nice to have some means of telling the compiler
that the unsigned variable will *never* rise above some specified
value. Some sort of pre-/postcondition perhaps. assert() doesn't
really suffice IMHO.

Cheers,
Per Erik Stendahl
berrs@hotmail.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]