lint, pointers, 0 (what else?)

Guy Harris guy at rlgvax.UUCP
Thu Feb 7 04:07:35 AEST 1985


> Many functions in 'C' return helpful values, which can, however, safely
> be ignored most of the time. Cluttering your code with '(void)' may
> look impressive and improve your productivity (in lines/hour), but is not
> going to help the portability or readability of your program. In
> particular, putting in the cast to void can become as much of a reflex
> leaving it out.

Sorry, Doug is right; explicitly flagging discarded return values is
often useful - it warns the reader that the code may not be checking
for error returns (if I had a nickel for each time I've been burned by
a program not checking for error returns I could single-handedly eliminate
the deficit).

> [sizeof(int)!=sizeof(char *)]
> 
> Sure, K&R did not explicitely demand anything else. Many programmers,
> due to the lack of a standard document, and due to the universal
> acceptance of sizeof(int)==sizeof(char *) in the early days of 'C',
> have written many of programs that rely on it, though. It is moot to
> argue that these programmers were wrong: their programs still exist,
> work, and are used (ever cc'ed 'sed'?).

So?  Before "termcap" existed, people wrote programs that controlled display
terminals by directly using control strings which were compiled into
the program.  These programs still exist, work, and are used, but they are
useless at a site which doesn't have the terminal they were written for.
*Modern* programs should be written to use things like "termcap", and
old programs may have to be rewritten.  That's life.  We had to bash a
number of System III programs to make them more type-correct to run on
our 16-bit-"int"/32-bit-pointer machine (and to keep them from trying
to dereference null pointers).

> Apart from habit, there are also the problems you will run into when
> implementing the generic null pointer

"Implementing the generic null pointer" is like "trisecting an angle
with compass and straightedge".  There is no generic null pointer in C
(as has been pointed out in this newsgroup far too many times already).
As such, the problems of "implementing the generic null pointer" are
irrelevant.
> 
> Finally, there is no good reason for not having
> sizeof(int)==sizeof(char *).  'int' is not guaranteed to be the fastest
> integer type around

To quote from K&R (p. 183):

	``Plain'' integers have the natural size suggested by the
	host machine architecture...

The Motorola 68000 speaks with forked tongue here.  16 bits is suggested
by the 16-bit data paths used for non-address arithmetic (2 extra clocks
for a 32-bit "add", f'rinstance), by the lack of 32-bit multiply or
divide instructions, and by the 16-bit external bus.  32 bits is suggested
by the large address space.  There is, thus, a good reason for having
sizeof(int) == 2 and sizeof(char *) == 4 - speed of execution.  There is
also a good reason for having them both == 4 - it would be nice to have
an "int" hold the size of an object larger than 65535 bytes.  There's
a tradeoff here; depending on your application, either one could be the
correct choice.

> And if you are worried about getting an efficient integer type portably,
> why don't you just use 'typedef short EfficientInt;' :-?

That's the best solution, but it doesn't help completely; arguments to
procedures have to be widened to "int".

> [null pointer]
> 
> I don't care whether the null pointer spells out Mona Lisa in EBCDIC,
> as long as I can compare it to '0', assign it as '0', and (sorry, I
> like it) pass it as '0' where a pointer should go -- without casting,
> the way K&R intended

Oh?  Have you asked K or R about this?  Do you think that the following
code:

	double foo(x)
	double x;
	{
		double sqrt();

		return(sqrt(x));
	}

	main()
	{
		printf("%f == 2\n", sqrt(4));
	}

should work?  It doesn't.  You have to cast the "4" to "(double)4", because
the current C language has no way of telling the compiler that arguments
passed to "foo" should be cast to "double".  The same holds true for
pointers.  The ANSI C language standard permits you to declare the
types of the arguments of a function, which makes 99% of these problems
go away.

> While we are on the subject, what about the same treatment for '-1',
> the (de facto) standard error return value?

What?  What treatment?  Return values don't have this problem because
you can declare the return value of a function.  (BTW, it is NOT the
standard error return value; "fopen", for instance, returns a null FILE
pointer if it fails.)

> A 'C' compiler with sizeof(int)!=sizeof(char *) has severe problems in
> the real world (I speak from experience, I am working with one), and is
> not going to do you much good.

I am also speaking with experience, I am working with such a compiler, it
has done us quite a bit of good (it permits us to write our system and
applications code in C, and we *do* make money selling that code) - a
32-bit "int" compiler might do better, but further the deponent sayeth
not - and the main problems we have are not problems with the compiler,
but problems with people who don't take sufficient care when writing
code for it.

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



More information about the Comp.lang.c mailing list