Skip to content
Dibyendu Majumdar edited this page Jul 21, 2018 · 23 revisions

Notes

Pure and Applied C

Message-ID: <bnews.research.330>

Newsgroups: net.lang.c

Path: utzoo!decvax!harpo!npoiv!alice!research!dmr

X-Path: utzoo!decvax!harpo!npoiv!alice!research!dmr

From: research!dmr

Date: Mon Dec 27 06:19:21 1982

Subject: Pure and applied C

Posted: Mon Dec 27 01:36:35 1982

Received: Mon Dec 27 06:19:21 1982



John Levine wondered whether, in the call bar(x++) with x global,
bar would see the old or the incremented value of x.  The parameter
is clearly the old value; the question is whether the compiler might
be allowed to do the increment after the call.

Pure C gives little reassurance either way. "Otherwise, the order of
evaluation of expressions is undefined.  In particular the compiler considers
itself free to compute subexpressions in the order it believes most
efficient, even if the subexpressions involve side effects."

Applied C is a little more cautious.  Steve Johnson brought up this very
point when he was writing PCC, and I said that as far as I knew he was
entitled to delay the increment.  We agreed, though, that the result
might surprise people, and he decided not to rock the boat.
	Dennis Ritchie

Operator precedence

Message-ID: <bnews.research.310>
Newsgroups: net.lang.c
Path: utzoo!decvax!harpo!npoiv!alice!research!dmr
X-Path: utzoo!decvax!harpo!npoiv!alice!research!dmr
From: research!dmr
Date: Fri Oct 22 03:39:32 1982
Subject: Operator precedence
Posted: Fri Oct 22 01:04:10 1982
Received: Fri Oct 22 03:39:32 1982

The priorities of && || vs. == etc. came about in the following way.
Early C had no separate operators for & and && or | and ||.
(Got that?)  Instead it used the notion (inherited from B and BCPL)
of "truth-value context": where a Boolean value was expected,
after "if" and "while" and so forth, the & and | operators were interpreted
as && and || are now; in ordinary expressions, the bitwise interpretations
were used.  It worked out pretty well, but was hard to explain.
(There was the notion of "top-level operators" in a truth-value context.)

The precedence of & and | were as they are now.

Primarily at the urging of Alan Snyder, the && and || operators were
added. This successfully separated the concepts of bitwise operations and
short-circuit Boolean evaluation.  However, I had cold feet about the
precedence problems.  For example, there were lots of programs with
things like
	if (a==b & c==d) ...
In retrospect it would have been better to go ahead and change the precedence
of & to higher than ==, but it seemed safer just to split & and &&
without moving & past an existing operator. (After all, we had several
hundred kilobytes of source code, and maybe 3 installations....)
	Dennis Ritchie

Sign extension

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!linus!genrad!mit-eddi!mit-vax!eagle!alice!research!dmr
From: dmr@research.UUCP
Newsgroups: net.lang.c
Subject: re type casting
Message-ID: <353@research.UUCP>
Date: Thu, 9-Jun-83 23:54:56 EDT
Article-I.D.: research.353
Posted: Thu Jun  9 23:54:56 1983
Date-Received: Fri, 10-Jun-83 11:37:43 EDT
Lines: 22

decvax!betz wondered about the construction

	char c;
	...  (unsigned) c;

His example was more complicated but this is the essence.  What is supposed
to happen is that the character is promoted to int, then cast to unsigned.
In other words, the sign extension is not prevented (which is what he
wants to accomplish, as portably and cheaply as possible).

In other words the v7 and DECUS compilers are wrong.  Unfortunately
they are not wrong by accident, or at least my compiler isn't.
To my shame I put in the construction as a special hack to accomplish
essentially the same thing as Betz wanted.  (This was before the unsigned
char type went in.)  In such ways do one's past sins come back to haunt one.

If you really want portability to compilers that don't have unsigned char,
I'm afraid you'll have to use the explicit mask.  At that, it may
not be too bad.  The 11 code generator would need to generate the mask
instruction anyway, and the Vax -O optimizer is smart enough to get rid of it.

		Dennis Ritchie

foo()*0

Message-ID: <bnews.research.329>
Newsgroups: net.lang.c
Path: utzoo!decvax!harpo!eagle!mhtsa!alice!research!dmr
X-Path: utzoo!decvax!harpo!eagle!mhtsa!alice!research!dmr
From: research!dmr
Date: Tue Feb  1 02:08:40 1983
Subject: foo()*0
Posted: Mon Jan 31 02:52:38 1983
Received: Tue Feb  1 02:08:40 1983

A couple of years ago I changed my C compiler not to throw out
0*x, 0&x, and the like where  x  is an expression with side effects.
I believed then and now that anyone who depended on such things was
mad, and the recent examples have not convinced me otherwise.
However, it was much easier to change the compiler than to attempt
to argue the implausibility of each carefully crafted example.
This is known in the trade as "covering your ass."

The change occurred post-v7 so it is not visible outside Bell.

		Dennis Ritchie

enums

Message-ID: <bnews.research.315>
Newsgroups: net.lang.c
Path: utzoo!decvax!harpo!npoiv!alice!research!dmr
X-Path: utzoo!decvax!harpo!npoiv!alice!research!dmr
From: research!dmr
Date: Mon Nov  8 03:18:21 1982
Subject: enums
Posted: Mon Nov  8 02:16:38 1982
Received: Mon Nov  8 03:18:21 1982

There has been a lot of grousing about the uselessness of the enum type
in C, most of it justified under the circumstances.  The circumstances
are that all versions of PCC that I know of are buggy in their treatment
of this type.

Enums were intended to be entirely equivalent to ints; just a way, really,
of defining names for constants understood by the compiler and subject
to the normal scope rules.

There was a clear choice here: enums as utterly separate collections of atoms,
more or less as in Pascal, or as ways of naming integers.  I chose the
latter after some waffling.  Unfortunately, some of the waffle batter
got mixed in with PCC and has stayed there.

		Dennis Ritchie

Type conversion

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!linus!decvax!harpo!eagle!allegra!alice!research!dmr
From: dmr@research.UUCP
Newsgroups: net.lang.c
Subject: bug in type conversion
Message-ID: <1021@research.UUCP>
Date: Wed, 4-Jan-84 00:32:17 EST
Article-I.D.: research.1021
Posted: Wed Jan  4 00:32:17 1984
Date-Received: Thu, 5-Jan-84 01:18:44 EST
Lines: 14

Mike O'Brien points out that in the C compilers he has available, the
expression
	i *= d;
where  i  is int and  d  is double is evaluated in fixed point, and
wonders why.  The answer: it is a compiler bug.  I fixed it in
(a post V7 version) of the 11 compiler, and it is fixed in the current
System V compiler (by "current" I mean the one I tried;
I don't know what is being shipped at this instant.)

The manual is reasonably clear and unambiguous on the point, but
it's not surprising that people for search for definition problems when
the compilers are unanimously wrong.

		Dennis Ritchie

Casts

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!allegra!alice!dutoit!dmr
From: dmr@dutoit.UUCP
Newsgroups: net.lang.c
Subject: conversion of short to unsigned int
Message-ID: <2026@dutoit.UUCP>
Date: Wed, 27-Mar-85 00:25:47 EST
Article-I.D.: dutoit.2026
Posted: Wed Mar 27 00:25:47 1985
Date-Received: Thu, 28-Mar-85 00:16:25 EST
Lines: 31

Mike Wescott wondered why, after

	unsigned short us = -3;
	short s = -3;

the comparison

	(unsigned int)s == us

should yield true (this, evidently, on a VAX).  The reason is that
his compiler, along with those of a great many people,
has a bug.  The short  s  should indeed promote to 0xfffffffd (an int)
and then be cast to unsigned (same bits, in 2's complement), and compare
unequal with the 0xfffd stored in  us .

This is another instance where a reasonably clear, if complicated,
description in the manual appears hopelessly confused because the
compiler doesn't implement the manual.

Incidentally, Ken Turkowski's remarks about casts: "... a cast, saying
that  s  is considered unsigned rather than signed.  It [a cast] is NOT
a conversion"  are quite wrong.  Casts specify conversions, not
requests to reinterpret a variable as containing some type other than
its own.  Many casts, especially those involving unsigned, or pointers,
do indeed not actually change any bits in the value.  This fact may have misled
Ken, and probably also the compiler writer.  The way to think of casts
is to imagine assigning their operands to temporary variables with
the type specified by the cast, and then using the temporary in the larger
expression in which the cast occurs.

	Dennis Ritchie
Clone this wiki locally