sizeof, ptrs, lint, portability

Guy Harris guy at rlgvax.UUCP
Sun Feb 10 05:04:01 AEST 1985


> -) I am shocked to find out that pointers may be of different sizes, &
>    may be of a different size than int. This has been true for so long
>    many people just assumed it. I believe it should be true wherever possible
>    for the following reason: if a default exists, it should be a useful one.
>    Defining different sizes for these items gives credibility to the
>    claim that C is dangerous. Just another accident waiting to happen.

The existence of automobiles is also "an accident waiting to happen" (although
it didn't wait very long) in those terms.  I don't blame the automobile,
I blame the driver.  I have no interest in seeing a governor placed on
all cars that limits speed to 35MPH.  Nor do I have an interest in seeing
the requirement that all pointer types must be represented the same way
placed on the C language.  If people can't cope with machines that require
(or, at least, strongly prefer) different pointer representations, that's
their problem, not C's.

> -) Perhaps you forgot some of the attraxions of the language: a terse
>    language that modelled the machine closely. No stupid booleans.
>    All those casts are ugly. How are we to convert people to C if they
>    must put up with all that verbosity? Shouldn't the compiler know?

That's why the ANSI C standard improved the declaration syntax for functions;
yes, the compiler should know, and ANSI C compilers do know (except for
functions with a variable number of arguments; the prime offender, "execl",
is just syntactic sugar for something that can be done equally well with
"execv").

> -) I apologize for calling (presumably someone's favorite) machines `weird'
>    or `braindamaged'. Let's say `less capable'. The pdp-11 was a landmark
>    in machine design. It was byte addressable, had a stack, memory mapped
>    i/o, an orthogonal instruxion set, and useful addressing modes. The
>    vax continued this trend. Most micros (all?) are byte addressable.

According to the Stanford MIPS people (see "Hardware/Software Tradeoffs
for Increased Performance" in the Proceedings of the Symposium on Architectural
Support for Programming Languages and Operating Systems, SIGARCH Computer
Architecture News V10#2 and SIGPLAN Notices V17#4), you may be better off
if you have a word-addressed machine and special pointers for accessing
bytes.  (In their case, byte and word pointers are both 32 bits long, but
coercions are still not copies.)

>    Most have an address space two to the size-of-register-in-bits power.

As has been said more times than I care to count, the 68000s registers are
32 bits long but 32 bit arithmetic is less efficient than 16 bit arithmetic.
I think that this is unfortunate, but it's a fact of life.  There are good
things to be said for 16-bit "int"s on a 68000.

>    This sort of machine is an inhospitable host for the C language and
>    some implementations are downright kluges. I claim that they don't
>    run C but another language I would call `C--'.

You aren't the arbiter of the C language; if you want to hold that opinion
you're welcome to it, but I suspect most people wouldn't agree.  UNIX runs
on the Sperry 1100; if users of UNIX on that machine (or other putatively
"inhospitable" machines) have any comments on that point, I'd like to hear
them.

> -) While you are claiming that it is MY CODING PRACTICES (and evidently
>    hordes of others, including 4.2bsd & sys III implementors) that are
>    nonportable, I am claiming that it is THOSE WEIRD MACHINES that are
>    nonportable. By changing the rules in the middle of the game, you
>    are depriving me (and others) of the time honored tradition of punning.

Aside from any semantic quibbles about the meaning of "nonportable", I
object to the reference to the "time honored tradition of punning".
Lots of traditions, like self-modifying code, were "time-honored" in the
days of small slow machines which "needed" that sort of stuff.  I can
get away without punning 99.9% of the time; the other .1% of code can
be "#ifdef"ed, or written in assembly language, or...

> -) I still maintain that assigning zero to a pointer stores an unspecified
>    number of zero bits.

Maintain what you will, the *language spec*, such as it is, says no such
thing.  Your statement is merely a statement of preference, which people
are at leisure to ignore.

> The null ptr is an out-of-band value. We agreed to represent it in-bound.

Who's "we"?  On many machines, there *is* no out-of-band value.  On the
VAX, 0xffffffff is arguably an out-of-band value, while on most UNIXes
on the VAX 0x0 is an in-band value.  On other machines, there *is* an
out-of-band value, specified by the architectural spec as "how to represent
a null pointer", and it need not consist of N 0 bits.

> Still, a piece  of kernel code should be able to pick up the byte at
> address zero by:
> 		int j; char *p; p = 0; j = *p;
>    Allowing any other value to actually be stored breaks this.

However, it doesn't break

	int j; char *p; j = 0; p = j; j = *p;

Admittedly, this is slightly less efficient, but the number of times when
you execute code that is intended *only* to fetch the contents of location
0 (as opposed to code that fetches the contents of an arbitrary location;

	peek(addr)
	int addr;
	{
		return(*(char *)addr);
	}

even works if you say "j = peek(0)") is very small.

> Besides, SHOW ME A C THAT USES ANYTHING OTHER THAN ZERO ON ANY MACHINE!!!

Hello?  Anybody from the Lawrence Livermore Labs S-1 project out there?
Don't you have a special bit pattern for the null pointer?

>    K&R says of pointer to integer conversions: "The mapping funxion is
>    also machine dependent, but is intended to be unsurprising to those
>    who know the machine." I would be surprised at nonzero null ptrs.

A subtle point; given a "char *" variable "p", the statement

	p = 0;

is different in character from both the statements

	p = 1;

and the statements

	i = 0;
	p = i;

given an "int" variable "i".  Arguably, this is confusing and a mistake, but
it is the clearest (and, probably, only correct) interpretation of what
K&R says on the subject.  The latter two sets of statements do this
particular mapping; the former one is a special case which shoves a null
character pointer into "p".  The mapping function in the third set of
statements is unsurprising.  If I ran the zoo, there would have been a
special keyword "nil" or "null", and THAT would have been the way to
specify null pointers; 50% of all these discussions wouldn't have occurred
if that was done.  Unfortunately, it's too late for that.

> -) Guy: if I want the square root of four, I do sqrt(4.0); NO CAST!

That's because the C language has a way of representing floating-point
constants directly.  It doesn't have a way of representing null pointers
directly; instead, it has a sneaky language rule that says the symbol
"0", when used in conjunction with a cast to a pointer or an expression
involving pointers, is interpreted as a null pointer of the appropriate
type.  If there were, say, a null pointer operator like "sizeof", like

	null(char *)

you could pass null(char *) to a routine.  Alternatively, if the language
had permitted you to declare the types of the arguments to a function
since Day 1, calling a function which expects a "char *" as an argument
would be an expression involving pointers and the 0 (or "nil" or "null")
would be interpreted as a null pointer to no character.

> -) How many of you port what percentage of programs? I thought the
>    intent of the standard was to not break existing programs. I claim
>    that the standard should recognize the existing idioms.

No, the intent of the standard is not to break existing *correct*
programs.  There exist programs, written by people at, among other places,
a certain large West Coast university, which assume that location 0
contains a null string (although that crap seems to have disappeared as
of 4.2BSD).  Does this mean that all implementations of C must map
location 0 into the address space and must put a zero byte there?

"=+" was a legal part of the language once.  It has now disappeared; the
System V compiler now only accepts "+=".  More and more programs are properly
declaring functions, casting pointers, etc..  As such, I see no point in
supporting the passing of undecorated 0s to functions whose argument types
are undeclared as the passing of a null pointer.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy



More information about the Comp.lang.c mailing list