Subject: Re: bin/7592: programs' error handle broken by good intentions
To: None <gnats-bugs@gnats.netbsd.org,>
From: Greg A. Woods <woods@most.weird.com>
List: netbsd-bugs
Date: 05/26/1999 21:02:18
[ On Wednesday, May 26, 1999 at 23:02:56 (+0200), Olaf Seibert wrote: ]
> Subject: Re: bin/7592: programs' error handle broken by good intentions
>
> Since we're discussing "traditional C", all references will be to
> Kernighan & Ritchie, 1st edition.

Actually, I specifially used the term "traditional C" to avoid calling
it K&R, and particularly to avoid reference to the infamous 1st edition.
If a few more people had bought the ill-fated "second" edition (1983, I
think -- it was pulled from the shelves just as the ANSI group began
working on a C standard, and I sorely regret not buying the copy I saw),
then I'd have referred to it.  It more accurately described a language
compatible with modern (at the time) UNIX C (i.e. the one that permits
structure assignment and has some other features such as 'unsigned long'
that slightly post-date the original 1st edition).  I'm most interested
in real UNIX C as implemented in the V7 Portable C Compiler and those
that grew from it and as described in the UNIX C Language Manual,
especially since K&Rv1 was out of date before it was published.

In any case you have me at a disadvantage -- all my books are still
packed in boxes in the garage, including K&Rv1 & v2 and my UNIX C
Language Manuals....  I'll comment based on memory....

> Not true. The "usual arithmetic conversions" are described on p.41
> and pointers are not mentioned there. Which is for the better, since a
> pointer is not an arithmetic type.

Well, actually, pointers *are* arithmetic types -- most arithmetic
operators can be used with them, though sometimes with results that
differ from those that would be expected on strictly integer types.

> Not true. See p.102, section 5.6, conveniently titled "Pointers are not
> Integers". 

No, they're not strictly an integer type -- they are often wider (more
bits), and some operators, such as '+', '-', '++' and '--' have
different effects on them than those same operators would have on an
'int' or 'long int', etc.  However in all other respects they are the
same as integers (and IIRC there's even such a statement in K&Rv1, if
not even examples of it).

IIRC, K&Rv1 conveniently left issues of pointer alignment rather vague
in order to give compiler writers some degree of freedom.

> This was already the case with "traditional C", see the top of p.98,
> where NULL is explained:
> 
>     In general, integers cannot meaningfully be assigned to pointers,
>     zero is a special case.

If you delve further into the meaning of that statement you'll find that
it doesn't have *anything* to say about what type coercions happen when
integers are assigned to pointers.  It simply means that you won't
likely point to anything if you assign any other arbitrary integer value
to a pointer.  In traditional C you can successfully transport a pointer
value through an integer variable if it is sufficiently wide (and
unaffected by sign extension).  You can also successfully add and
subtract integer offsets to/from pointer values (so long as you know
what you're doing! ;-).

> Huh? I don't think you mean what you write here - why would you want to
> make p = -1 do the same as p = 0 ?

No, obviously not.  I was referring to the way the language treats the
types, not the way it treats the actual values -- quite the contrary!  I
simply want to be able to pass other integer values that are equally
unlikely to ever point at a valid object through pointer types.

Indeed the Unix libraries are littered with examples of using
'(some_type *)-1' as some way of returning an error from a function
(where returning NULL is not an error, merely perhaps an indication that
a search failed without error, etc.).

> I agree that #define NULL ((void *)0) is not a good idea, since that is
> a null object pointer and cannot be converted into a null function
> pointer.

Actually in the C9X draft [which I do have a local electronic copy of!]
(and I think in ANSI C) NULL can really be defined as above, but the
only way they get away with it is because of the special treatment of
the value '0' -- it is always coerced in an assignment or a function
parameter (except when the function is declared and defined with the
"traditional" syntax and no prototype is in scope).

Indeed the integer constant '0' can be cast and recast into any pointer
type, including a function pointer type, and never be adjusted by
alignment restrictions, and never lose it's meaning as the "null pointer
constant".

In fact I must regrefully point out that defining NULL as above will
eliminate my initial complaint, but two wrong's definitely do not make
it right.

> The C you want is very much alive in my V6 installation. I suggest you
> download one too, and a PDP-11 emulator.

V7 Pllleeease!  V6 was not much more than a toy, a proof of concept,
even within the Labs.  I've already downloaded V7, and no, I don't
really need the emulator either!  ;-)  I know where to get access to a
running V10 system locally too, but that's not the point.

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>