[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: minus operator applied to unsigned type
On Mon, 29 Nov 2010, der Mouse wrote:
> > My compiler is confused. What does this mean?
> > d_val = str == '-' ? -(double)-l_val : (double)l_val;
> I'm not sure why the -(double)-l_val construct. I suspect the intent
> is to convert an unsigned long holding a signed long's bit pattern to a
> double with the same value as the signed long.
Yes, that's what I assumed, and I believe that the original code
correctly implements that intent. I would probably have prenthesised it
d_val = (str == '-' ? -(double)(-l_val) : (double)l_val);
> If so, I can't see why not (double)(long)l_val;
That invokes undefined behaviour, if l_val is an unsigned long whose
value is outside the range of positive integers that that can be
represented by a signed long. That will happen whenever the intent is
to deal with a negative number, because negative numbers stuffed into
unsigned long variables look like large positive numbers.
In this code:
signed long svar;
unsigned long uvar;
svar = -1; /* A */
uvar = svar; /* B */
svar = uvar; /* C */
assignment B stores a large positive value into uvar, and assignment C
invokes undefined behaviour because that large positive value is too
large to be represented as a positive value in svar.
> indeed, I think -(double)-l_val equals
> (double)(long)l_val except when l_val holds the (bit pattern of the)
> most negative long - or if signed longs don't use two's complement, I
> suppose, which it seems to me it is unlikely the code is designed to
I think I agree with you about what likely to happen on a machine that
uses two's complement, but I believe that the original code would have
worked with any underlying representation, and even when l_val is
intended to represent the most negative signed long.
> > There are several of these (for my compiler ambiguous) constructs in
> > bmake. [...] I solved them just by adding a zero - hope that's what
> > was originally meant.
As Mouse said, there's nothing ambiguous about the original code, but
changing -(double)-l_val to -(double)(0-l_val) will retain the same
meaning. You could also try -(double)(-l_val).
--apb (Alan Barrett)
Main Index |
Thread Index |