[comp.lang.c] What's Wrong here?

dave@westmark.UUCP (11/28/87)

Perhaps a C guru on the net can tell me what's wrong with this
trivial C program?

#include <stdio.h>
main()
{
	long n;
	n = (1 << 31) -1;
	printf("%ld\n", n);
}

This is a simple example of a problem that affects a more complex
piece of someone's software that I'm trying to maintain.

If I compile this under UNIX, and run it, it prints 2147483647.
If I compile this under MS-DOS using Microsoft C Rel 3.0, and run
it, it gets the same answer!!!  But if I compile it under MS-DOS
using Microsoft C Rel 4.0, it prints 65535.  Has anyone tried
something like this under Microsoft C Rel 5.0?

Am I mis-using C?   Is there a reason why the expression is
apparently evaluated as an int and then promoted to long in one
compiler but evaluated as a long in two others?
-- 
Dave Levenson
Westmark, Inc.		A node for news.
Warren, NJ USA
{rutgers | clyde | mtune | ihnp4}!westmark!dave

gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/29/87)

In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>	long n;
>	n = (1 << 31) -1;

Try changing the first "1" to "1L"; otherwise the whole expression
is evaluated using (int)s, not (long)s, before the value is assigned.
If (int) has 16 bits, the left-shift overflows and a variety of
results are possible, including the one you reported.

By the way, you're treading on thin ice anyway, since (1L << 31) is
the most-negative 2's complement integer, so subtracting 1 from it
is yet another undefined operation.  I'm not sure what this code is
trying to accomplish, but consider using
	unsigned long n;
	n = ((unsigned long)1 << 31) - 1;

platt@emory.uucp (Dan Platt) (11/29/87)

In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>Perhaps a C guru on the net can tell me what's wrong with this
>trivial C program?
>
>#include <stdio.h>
>main()
>{
>	long n;
>	n = (1 << 31) -1;
>	printf("%ld\n", n);
>}
>
>
>Am I mis-using C?   Is there a reason why the expression is
>apparently evaluated as an int and then promoted to long in one
>compiler but evaluated as a long in two others?

I don't know if it's a mis-use.  It would seem that there is some
ambiguity over the issue if not all compilers treat this the same.
It seems to me that most of the compilers that I've tried (on the Sun
the DEC, and TurboC) treat this as the long answer.  Yet I don't see
any reason why it should. I would say that to make absolutely sure,
you should code this as

#include <stdio.h>
main()
{
	long n;
	n = (1L << 31) - 1;
	printf("%ld\n",n);
}

and see if this fixes the problem.  If it doesn't then there's a bug in
MSC4.0 (which they may or may not have fixed by 5.0).

Dan Platt

ark@alice.UUCP (11/29/87)

In article <278@westmark.UUCP>, dave@westmark.UUCP writes:
> Perhaps a C guru on the net can tell me what's wrong with this
> trivial C program?
> 
> #include <stdio.h>
> main()
> {
> 	long n;
> 	n = (1 << 31) -1;
> 	printf("%ld\n", n);
> }

The value of the expression

	1 << 31

is undefined on implementations where an int is less than 32 bits long.

If you wish to evaluate 1<<31 as a long, you must write

	n = (1L << 31) -1;

or some variation thereof.

ugfailau@sunybcs.uucp (Fai Lau) (11/29/87)

In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>>	long n;
>>	n = (1 << 31) -1;
>
>Try changing the first "1" to "1L"; otherwise the whole expression
>is evaluated using (int)s, not (long)s, before the value is assigned.
>If (int) has 16 bits, the left-shift overflows and a variety of
>results are possible, including the one you reported.
>
	The left most bit of both long words of UNIX and Rel 3.0
are sign bits. The same is true for the integer of Rel 4.0.
When you "overshift" a word or integer, the sign bit can only
be shifted "on". That is, when the sign bit is turned on as
a result of bit shifting, it can not be turned off again,
unlike the other bits which represent the value of the
number. So, when you over shift a word of any length,
you'll always get a 1 on the left most bit, except in the
case where the word itself is 0 (ie. has no "on" bit).
	In the above case, a 16 bit word is overshifted.
What's left is a word with *only* the left most bit, the sign
bit, turned on. This bit pattern represents an integer
value of -65536 (I don't want to go into how the *value*
of a negative number is represented). When you put - 1 on it,
overthrow occurs, as the number -65536 is the smallest
integer a 16 bit word can represent. Therefore, instead
of -65537, you get a positive integer of 65535, with
every bit of the word turned on except the sign bit.
Incidently, this value is the maximum that can be
stored in the 16 bit word. Notice that every value
bit is used up. This value is then stored in the long word n.
That is why you got the value you did when you print n.
As a matter of fact, the supposedly correct value
you get from UNIX and Rel 3.0 is a result from
negative overflowing too. This value is the maximum
positive number that can be stored in the 32 bit long
words of UNIX and Rel 3.0.

>By the way, you're treading on thin ice anyway, since (1L << 31) is
>the most-negative 2's complement integer, so subtracting 1 from it
>is yet another undefined operation.  I'm not sure what this code is
>trying to accomplish, but consider using
>	unsigned long n;
>	n = ((unsigned long)1 << 31) - 1;

	The operation is not undefine. By observing the result,
we can 1) identify the scheme with which the system store negative
numbers, 2) what length of word is used as default for operation
like <<. Using much larger number in place of 31 doesn't hurt.
(not original intent, of course)

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs

chris@mimsy.UUCP (Chris Torek) (11/29/87)

In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>#include <stdio.h>
>main()
>{
>	long n;
>	n = (1 << 31) -1;
>	printf("%ld\n", n);
>}
>
>If I compile this under UNIX, and run it, it prints 2147483647.

(You do not say on which machine---probably one with 32 bit ints.)

>If I compile this under MS-DOS using Microsoft C Rel 3.0, and run
>it, it gets the same answer!!!  But if I compile it under MS-DOS
>using Microsoft C Rel 4.0, it prints 65535.

That is a bit peculiar.  I would expect 1<<31 to be (int)0, then
(int)0-(int)1 to be (int)-1, which should produce (long)-1 when
extended.

>Am I mis-using C?

Yes: use (1L << 31) - 1, or (1 << 31L) - 1, or ((long)1 << 31) -
1, or . . . .  If you shift something too many positions, I believe
the result is officially undefined; this gives MS C license to come
up with anything, including the rather ludicrous 65535, or the more
reasonable -1, or even 2147483647.  (I would be more certain but
my references are at work and I am not.)  At a guess, I would say
that MS C 3.0 noticed the shift count of 31 and put in the (long)s
for you, and that this feature(?) was removed from release 4.0.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

chris@mimsy.UUCP (Chris Torek) (11/29/87)

In article <6855@sunybcs.UUCP> ugfailau@sunybcs.uucp (Fai Lau) writes:
>	The left most bit of both long words of UNIX and Rel 3.0
>are sign bits. The same is true for the integer of Rel 4.0.
>When you "overshift" a word or integer, the sign bit can only
>be shifted "on". That is, when the sign bit is turned on as
>a result of bit shifting, it can not be turned off again, ....

This may be true for left shifts, although I doubt it.  It is
probably true for right shifts.

>	In the [original example], a 16 bit word is overshifted.
>What's left is a word with *only* the left most bit, the sign
>bit, turned on. This bit pattern represents an integer
>value of -65536 (I don't want to go into how the *value*
>of a negative number is represented).

Nonsense.  The pattern 0x8000 as a signed two's complement 16
bit value represents -32768.

>>By the way, you're treading on thin ice anyway, since (1L << 31) is
>>the most-negative 2's complement integer, so subtracting 1 from it
>>is yet another undefined operation.  [Doug Gwyn]

>	The operation is not undefine.

Again, nonsense.  The result is undefined *in C*.  No doubt the
operation on any given system is predictable (though possibly with
difficulty: a compiler is free to implement underflow by replacing
the value with the time of day, or the apparent diameter of the
lit region of the moon, or soemthing equally absurd).  Most will
ignore the underflow and change 0x80000000 to 0x7fffffff; others
may trap and give you a core dump.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/30/87)

In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>That is, when the sign bit is turned on as
>a result of bit shifting, it can not be turned off again,

Is this REALLY true of the 80*86 family?  If so, it's the only
architecture I've ever heard of that behaves this way.

>	The operation is not undefine.

By "undefined" I meant, undefined by the C language specification.
Obviously the hardware will do SOMEthing.

jru@etn-rad.UUCP (John Unekis) (12/01/87)

In article <6761@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>That is, when the sign bit is turned on as
>>a result of bit shifting, it can not be turned off again,......
>Is this REALLY true of the 80*86 family?  If so, it's the only
>architecture I've ever heard of that behaves this way......
No, It is not true. I think Doug was confused by the difference between a
logical shift instruction, and an arithmetic shift. With either type of 
shift, a left shift places the next-to-most-significant bit into the 
most-signifacant-bit , whether it is a one or a zero. When you perform a 
right shift however, the logical shift moves everything down one bit and
turns off(makes zero) the high bit. The arithmetic shift moves everything
down one bit and leaves the high bit set to its previous value(whether one
or zero). Since the high bit is the sign bit, this leaves a negative number
negative after the shift. Microsoft C uses the arithmetic shift whenever 
you do a >> shift in C. This is nice in a way, because a right shift by 
one bit is always equal to a divide by two. That is 4 >> 1 = 2, and 
-4 >> 1 = -2.  It does however lead to some frustration if you are using 
shift operations to isolate something like bit flags. If you take a 16bit
integer and put the value 32767 in it, you get 0111111111111111 in binary,
a left shift gives you 1111111111111110, which is a -2, If you follow with
a right shift, you get 1111111111111111, which is a -1. So a right shift
is not always the inverse of a left shift in Microsoft C. If it is important
to you not to propagate the sign bit , I suggest you follow a right shift
with an and operation such as result = (value >> n) & (32767 >> (n-1)). It
is a horrible kludge, but it may be easier than coding an assembler routine
to perform a logical right shift instead of the arithmetic right shift.

I am not particularly fond of intel 80?86 hardware, but they are not 
THAT bad.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/01/87)

In article <312@etn-rad.UUCP> jru@etn-rad.UUCP (John Unekis) writes:
-In article <6761@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
->In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
->>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
->>That is, when the sign bit is turned on as
->>a result of bit shifting, it can not be turned off again,......
->Is this REALLY true of the 80*86 family?  If so, it's the only
->architecture I've ever heard of that behaves this way......
-No, It is not true. I think Doug was confused by the difference between a
-logical shift instruction, and an arithmetic shift. ...

I'm afraid I confused you by including one too many "... writes:" lines.
I (Doug) am well aware of the differences between types of shifts.
However, Fai Lau posted a fascinating "correction" to my correct response,
claiming a new and unusual form of brain damage, presumably for the 80*86
architecture (since these messages have been cross-posted to comp.sys.ibm.pc).

-I am not particularly fond of intel 80?86 hardware, but they are not 
-THAT bad.

I didn't think it could really be..

tim@amdcad.AMD.COM (Tim Olson) (12/01/87)

In article <312@etn-rad.UUCP> jru@etn-rad.UUCP (John Unekis) writes:
|                       ... Microsoft C uses the arithmetic shift whenever 
| you do a >> shift in C. This is nice in a way, because a right shift by 
| one bit is always equal to a divide by two. That is 4 >> 1 = 2, and 
| -4 >> 1 = -2.

This is not true.  First of all, right shift is not guaranteed to be
arithmetic for signed integers.  Second, most computers and languages
define integer divide to round towards zero, not negative infinity. 
Therefore, substituting >> for a division by a power of 2 is not correct
(unless you also include the fixup code for odd negative dividends).

| If it is important
| to you not to propagate the sign bit , I suggest you follow a right shift
| with an and operation such as result = (value >> n) & (32767 >> (n-1)). It
| is a horrible kludge, but it may be easier than coding an assembler routine
| to perform a logical right shift instead of the arithmetic right shift.

Why not just use unsigned operands?  Right shift is required to be
logical (zero-fill) for unsigned ints.

	-- Tim Olson
	Advanced Micro Devices
	(tim@amdcad.amd.com)

ugfailau@sunybcs.uucp (Fai Lau) (12/02/87)

In article <9562@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <6855@sunybcs.UUCP> ugfailau@sunybcs.uucp (Fai Lau) writes:
>> .....
>>be shifted "on". That is, when the sign bit is turned on as
>>a result of bit shifting, it can not be turned off again, ....
>
>This may be true for left shifts, although I doubt it.  It is
>probably true for right shifts.
>
	It *is* true for every version of C I've ever worked on.
I don't know about the machines. I made a mistake by not mentioning
the shift is "left" shift. I am not sure know about right shift.
The result puzzles me too. I remember I've worked on bit shifts
on C before, it took me a lot of agony to realize this characteristic.

>>	In the [original example], a 16 bit word is overshifted.
>>What's left is a word with *only* the left most bit, the sign
>>bit, turned on. This bit pattern represents an integer
>>value of -65536 (I don't want to go into how the *value*
>>of a negative number is represented).
>
>Nonsense.  The pattern 0x8000 as a signed two's complement 16
>bit value represents -32768.
>
	True. I forgot the positive half. 16 bits can only represent
65536 integers. With 32767 positive integers and one 0, there are
only 32768 negative integers. But the misinterpretation of the
16th bit still holds true.

>
>>	The operation is not undefine.
>
>Again, nonsense.  The result is undefined *in C*.  No doubt the
>operation on any given system is predictable (though possibly with
>difficulty: a compiler is free to implement underflow by replacing
>the value with the time of day, or the apparent diameter of the
>lit region of the moon, or soemthing equally absurd).  Most will
>ignore the underflow and change 0x80000000 to 0x7fffffff; others
>may trap and give you a core dump.
>-- 
	It is all in how you see it. If you know the behavior
of your machine, you can no doubt use the over flow characteristic
as a defined function. A function which returns an undefined result
in certain input circumstances can be considered defined in all
input circumstanc if the undefined output is predictable and
is indeed included in the set of output which is considered,

$$$filler
$$$filler is a necessary evil
$$$filler
$$$filler
???Enough???

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs

ugfailau@sunybcs.uucp (Fai Lau) (12/02/87)

In article <6761@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>That is, when the sign bit is turned on as
>>a result of bit shifting, it can not be turned off again,
>
>Is this REALLY true of the 80*86 family?  If so, it's the only
>architecture I've ever heard of that behaves this way.
 
	Oops. I should have emphasized that it *can* be turned off!!
But using other ways except left shift (logical bits operations
come to mind).

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs

ugfailau@sunybcs.uucp (Fai Lau) (12/02/87)

In article <6767@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <312@etn-rad.UUCP> jru@etn-rad.UUCP (John Unekis) writes:
>-In article <6761@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>->In article <6855@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>->>In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>->>That is, when the sign bit is turned on as
>->>a result of bit shifting, it can not be turned off again,......
>->Is this REALLY true of the 80*86 family?  If so, it's the only
>->architecture I've ever heard of that behaves this way......
>-No, It is not true. I think Doug was confused by the difference between a
>-logical shift instruction, and an arithmetic shift. ...
>
>I'm afraid I confused you by including one too many "... writes:" lines.
>I (Doug) am well aware of the differences between types of shifts.
>However, Fai Lau posted a fascinating "correction" to my correct response,
>claiming a new and unusual form of brain damage, presumably for the 80*86
>architecture (since these messages have been cross-posted to comp.sys.ibm.pc).
>
	It's a no-no, Doug. For a while I thought you had to be one
of those mischievious little brats that whouldn't listen but keep
insisting on fooling around with their old man's PC. But then I
had my doubt. You know how to spell "brain damage".
	Nevertheless It is quite amusing to observe the hilarity
of your attempt at commanding the written language. Despicable
manners aside, your inability of organizing ideas in words can
only be matched by your ignorance of facts so prominently displayed
in your paltry writing. As those of us who have noticed that
particular article I posted have already know, the only
thing that I even came close to "correcting" you was on the
issue of whether overshifting in C is defined. I had my
opinion. And I was speaking more from a system point of
view. I wasn't interested in the science of the programming
language. But of course this whole thing I wrote left your
miniscule mind utterly perplexed and hopelessly confused.
But then I had no intention of lowering myself to speak at
your level.

	Well, folks, I better stop before it gets out of hand.
I understand that this kind of bantering is very inappropriate
for this news group, but someone's got to do the dirty
job of putting Doug in his place, before he again posts anything 
offensive and mindless they way he did. Remember, Doug,
a man is never too old to learn, or too young to get
spanked! ;-):-);-):-);-P:-|;-P:-|

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/02/87)

In article <6949@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>Remember, Doug, a man is never too old to learn, or too young to get spanked!

I don't know who this turkey thinks he is, but regular readers of the
C newsgroup undoubtedly are in a position to make up their own minds
about the reliability of the various contributors to the recent
discussion about the behavior of shift operators (which really had
little to do with the original question!).

mcdonald@uxe.cso.uiuc.edu (12/02/87)

/* Written  6:37 pm  Nov 30, 1987 by jru@etn-rad.UUCP in uxe.cso.uiuc.edu:comp.lang.c */
negative after the shift. Microsoft C uses the arithmetic shift whenever 
you do a >> shift in C. This is nice in a way, because a right shift by 
/* End of text from uxe.cso.uiuc.edu:comp.lang.c */

Only on signed quantities. Consider this C subroutine and the compiler output
(dead code deleted):

a(b,c)
int b;
unsigned c;
{
   b >>= 1;
   c >>= 1;
}

_a	PROC NEAR
	push	bp
	mov	bp,sp
	sar	WORD PTR [bp+4],1	;b    sar is arithmetic
	shr	WORD PTR [bp+6],1	;c    shr is logical
	mov	sp,bp
	pop	bp
	ret	
a	ENDP

Doug McDonald

sdutcher@netxcom.UUCP (Sylvia Dutcher) (12/03/87)

I have checked a couple pf references and have found the following defenitions.

ARITHMETIC SHIFT - An arithmetic shift is a microoperation that shifts a 
*signed* binary number to the left or right.  An arithmetic shift-left
multiplies a signed binary number by 2.  An arithmetic shift-right divides
the number by 2.  Arithmetic shifts must leave the sign of the number 
unchanged because the sign of the number remains the same when it is 
multiplied or divided by 2.  (Mano, Digital Logic and Computer Design, p329)

LOGICAL SHIFT - A shift operation with 0 inserted in the extreme bit is
considered a logical shift microoperation. (Ibid, p339)

Just to confuse things, Kernighan & Ritchie say (p45)
" ... x << 2 shifts x left by two positions, filling vacated bits with 0;
this is equivalent to multiplication by 4.  Right shifting an *unsigned*
quantity fills vacated bits with 0.  Right shifting a signed quantity will
fill with sign bits ("arithmetic shift") on some machines .....and with
0-bits ("logical shift") on others.

So I guess you're all right!
-- 
Sylvia Dutcher
NetExpress Communications, Inc.
1953 Gallows Rd.
Vienna, Va. 22180

john@frog.UUCP (John Woods, Software) (12/03/87)

In article <6949@sunybcs.UUCP>, ugfailau@sunybcs.uucp (Fai Lau) writes:
>[A maze of twisty little 'In article <foo>, {baz} writes:' deleted]
> >I (Doug) am well aware of the differences between types of shifts.
> >However, Fai Lau posted a fascinating "correction" to my correct response,
>
>	It's a no-no, Doug. For a while I thought you had to be one
> of those mischievious little brats that whouldn't listen but keep
> insisting on fooling around with their old man's PC. But then I
> had my doubt. You know how to spell "brain damage".
> 	Nevertheless It is quite amusing to observe the hilarity
> of your attempt at commanding the written language. Despicable
> manners aside, your inability of organizing ideas in words can
> only be matched by your ignorance of facts so prominently displayed
> in your paltry writing.

I find this truly amazing.  One of the most professional fonts of wisdom
on comp.lang.c (namely Doug) is being flamed by some idiot who clearly doesn't
understand anything more complicated than how to boot his PC.

> issue of whether overshifting in C is defined. I had my
> opinion. And I was speaking more from a system point of
> view. I wasn't interested in the science of the programming
> language.

In short, it IS NOT defined, your opinion is worthless, and evidently
you weren't interested in understanding what you were talking about,
either.  (What "system point of view"?) Try shutting up until you do.

>Remember, Doug, a man is never too old to learn, or too young to get spanked!
> Fai  Lau

Wise words.  Remember them yourself, or get ready to be spanked by everyone
on USENET who knows what they're talking about.  That's fewer than it should
be, but more than you would want.


--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw@eddie.mit.edu

"Cutting the space budget really restores my faith in humanity.  It
eliminates dreams, goals, and ideals and lets us get straight to the
business of hate, debauchery, and self-annihilation."
		-- Johnny Hart

lmiller@venera.isi.edu (Larry Miller) (12/03/87)

In article <6949@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>	Well, folks, I better stop before it gets out of hand.
>I understand that this kind of bantering is very inappropriate
>for this news group, but someone's got to do the dirty
>job of putting Doug in his place, before he again posts anything 
>offensive and mindless they way he did. Remember, Doug,
>a man is never too old to learn, or too young to get
>spanked! ;-):-);-):-);-P:-|;-P:-|
>
>Fai  Lau
>SUNY at Buffalo (The Arctic Wonderland)
>UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
>BI: ugfailau@sunybcs


As a regular reader of this news group, and as someone who as written
or co-written several programming language texts, I think Doug's
contributions to this group have been accurate, timely, and a boon to
all C programmers.  The time and effort he puts in to contributions
to this group are enormous, and frankly, beyond what one would hope
for.  It would be a shame if he were to decide not to involve himself
because of this thoughtless, ugly, posting my Mr. Lau.

Larry Miller				lmiller@venera.isi.edu (no uucp)
USC/ISI					213-822-1511
4676 Admiralty Way
Marina del Rey, CA. 90292

jru@etn-rad.UUCP (John Unekis) (12/03/87)

In article <19390@amdcad.AMD.COM> tim@amdcad.UUCP (Tim Olson) writes:
>In article <312@etn-rad.UUCP> jru@etn-rad.UUCP (John Unekis) writes:
>|                       ... Microsoft C uses the arithmetic shift whenever 
>
>This is not true.  First of all, right shift is not guaranteed to be
>arithmetic for signed integers.  Second, most computers and languages
.....
The discussion was not of MOST computers, it was regarding the Intel
80?86, and I specifically referenced Microsoft C, which does use the 
arithmetic shift for right shifting integers.

brianc@cognos.uucp (Brian Campbell) (12/03/87)

In article <6755@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
! In article <278@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
! >	long n;
! >	n = (1 << 31) -1;
! 
! Try changing the first "1" to "1L"; otherwise the whole expression
! is evaluated using (int)s, not (long)s, before the value is assigned.
! If (int) has 16 bits, the left-shift overflows and a variety of
! results are possible, including the one you reported.
! 
! By the way, you're treading on thin ice anyway, since (1L << 31) is
! the most-negative 2's complement integer, so subtracting 1 from it
! is yet another undefined operation.  I'm not sure what this code is
! trying to accomplish, but consider using
! 	unsigned long n;
! 	n = ((unsigned long)1 << 31) - 1;

I don't think this is good advice.  Unless the assigment is supposed to be
setting all bits except the 32nd, I think Dave should be assigning from a
define.  The LONG_MAX defined in <limits.h> sounds ideal, although its defined
in <values.h> and is called MAXLONG on my machine ...
-- 
Brian Campbell        uucp: decvax!utzoo!dciem!nrcaer!cognos!brianc
Cognos Incorporated   mail: POB 9707, 3755 Riverside Drive, Ottawa, K1G 3Z4
(613) 738-1440        fido: (613) 731-2945 300/1200, sysop@1:163/8

chris@mimsy.UUCP (12/04/87)

In article <314@etn-rad.UUCP> jru@etn-rad.UUCP (John Unekis) writes:
>The discussion was not of MOST computers, it was regarding the Intel
>80?86, and I specifically referenced Microsoft C, which does use the 
>arithmetic shift for right shifting integers.

The discussion was neither `of most computers' nor `regarding the
Intel 80?86': the discussion started with a question about the
language C, in which the type of right shift for signed integers
is left unspecified (at least in K&R).  It was placed in a context
which referenced Microsoft C, but the question itself was more
generic.  Never assume that mere mention of one particular means
that those reading your article will view it as being restricted
to that particular.

To John Woods, who flamed Fai Lau for flaming Doug Gwyn:  Please
do not be *too* harsh.  Fai Lau's point (which I regard as being
`by observing the results of various technically-undefined operations,
one can determine, to some extent, the inner workings of one's
system') is valid.  It is unfortunate that he had obscured that
point with incorrect `facts' and confusing wording.

I seem to be good at left-handed compliments!  Perhaps it is because
I am left handed. :-) At any rate, can we stop this discussion,
now that we have settled upon the following:

	In C as it is currently defined (K&R),
	- the result of left shifting an `int' value by 31 bits is 
	  undefined
	- the result of subtracting 1 from the most negative `int'
	  value a system can represent is undefined
	- whether right shift is arithmetic or logical is undefined

	In MS C for the IBM PC,
	- the `most negative' `int' value is -32768
	- right shift of a signed integer quantity is done with an
	  arithmetic (sign-preserving) shift
	- right shift of an unsigned integer quantity is done with
	  a logical (zero-filling) shift
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

ugfailau@sunybcs.UUCP (12/04/87)

	It is getting ridiculous. I will make my absolute last
post regarding this incident. I apologize for my last outburst.
As I said it was very inappropriate to post flame the way
I did in this news group, especially in such bad faith.
This is, after all, not the Insult Board of my school, which
I once took much pleasures in and from which I have retired. I
was very angry with Doug's name-calling post so I though that
that would be a pretty good excuse to try my skill, or whatever's
left of it. Again, I think my post was excessive. So in order
to be fair, I'll swallow John Woods' more juvenile portion of
his post without any rebuttal. And I don't want to see another
thing regarding this incident again.
	I wish I could move this article to soc.insult and
truly indulge myself at John Woods' expense, but then such
news group doesn't exist.  So I'll have to settle, and so
will everybody.

In article <1958@frog.UUCP> john@frog.UUCP (John Woods, Software) writes:
>
>I find this truly amazing.  One of the most professional fonts of wisdom
>on comp.lang.c (namely Doug) is being flamed by some idiot who clearly doesn't
>understand anything more complicated than how to boot his PC.
>
>In short, it IS NOT defined, your opinion is worthless, and evidently
>you weren't interested in understanding what you were talking about,
>either.  (What "system point of view"?) Try shutting up until you do.
>
	System point of view means to consider the behavior of
a software (or particular, a language) as a subset of the system.
There are many definitions regarding how many softwares ought
to behavior in an ideal environment, on paper, in theory,
according to formulas. But in the real world we have to
implement such ideals in an un-ideal machines, and used
by 'imperfect' humans. As a result there are things
ending up being different from the deffinitions and the theories.
For example, Lisp. The concept of Lisp looks like it's
the best thing ever happened to AI research (at least
when it first came out), and we certainly admired its
potentials at one time. Lisp is widely used today.
And you know what happens? It's just another programming
language. We recurse like a bat out of hell, and then
find out what a pain on the butt it could be keeping
track of those lists within lists. And we start using
setqs, iteration whenever it's more convenient.
Just how much spirit is left?  Are the original
wine and roses evident in our codes?
	Another example. When Modula-1 first came out, it was
supposed to be a very structured language which would
replace Pascal, and which would provide good low level access.
It incorporated data abstraction, the idea of modules,
better scope and extend controls, etc.. and the result should
be something less error prone and more complete. But so what?
Have Do you seen Turbo Modula-2? I've tried Modula-2 on mainframe.
What looks good on paper doesn't necessary work
well in the real world.
	So what am I getting at? Strict language definition
looks good in a text book. And it would be nice to be
followed precisely in the developing of theories. But
in the real world you cannot separate the language
from the machine it is being implemented in. Granted
portability may suffer if a programmer went beyond
what's in the book in his command of a language,
but if the circumstances allow it should not be
forbidden, or even discouraged. And of course it
is frequently done. Personally I don't like doing
things by the books. And I believe certain definitions
of a language is most useful when it is defined under
the circumstances where *you* use it.

>Wise words.  Remember them yourself, or get ready to be spanked by everyone
>on USENET who knows what they're talking about.  That's fewer than it should
>be, but more than you would want.
>
	See I swallowed it!

Fai  Lau
SUNY at Buffalo (The Arctic Wonderland)
UUCP: ..{mit-ems|watmath|rocksanne}!sunybcs!ugfailau
BI: ugfailau@sunybcs

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/04/87)

In article <6996@sunybcs.UUCP> ugfailau@joey.UUCP (Fai Lau) writes:
>I was very angry with Doug's name-calling post...

Perhaps you should try harder to understand things before reacting
to them.  If it was the epithet "brain-damaged" that you objected
to, be advised that it was directed at the architecture you
described (where sign bits stuck in the "on" state on a left shift).
This is standard terminology for architectural design defects.

A later poster has advised that the 80*86 architecture does not
behave the way you described it.  You can find out by running the
following test on your toy computer; I don't have convenient access
to one or I would have tried it myself:

#include <stdio.h>
main()
{
	register short i;	/* make sure it's 16 bits */
	register int j;
	for (i = 0x5555, j = 0; j < 16; ++j) {
		i <<= 1;
		if (j % 2 && i & 0x8000) {
			printf("Fai Lau was right!\n");
			return 0;
		}
	}
	printf("Gobble, gobble!\n");
	return 1;
}

>Personally I don't like doing things by the books.

The approach you said you take to the use of programming languages
will get you into great trouble when you have to port megalines of
source code to dozens of disparate environments.  Those of us who
have done this over the past couple of decades have learned how to
avoid, or at least harness, machine dependencies in our code.  We
most certainly DO discourage exploiting machine dependencies under
most circumstances, and C signed right-shift sign propagation (or
lack of it) is one of the things you should avoid relying on.  Try
taking advantage of other people's experience so you don't have to
learn everything the hard way.