Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site kobold.UUCP Path: utzoo!watmath!clyde!burl!ulysses!harpo!decvax!genrad!grkermit!masscomp!kobold!tjt From: tjt@kobold.UUCP Newsgroups: net.lang.c Subject: Re: if sizeof (char*) == 4 then sizeof (int) MUST = 4 (K&R) Message-ID: <283@kobold.UUCP> Date: Thu, 15-Mar-84 09:55:28 EST Article-I.D.: kobold.283 Posted: Thu Mar 15 09:55:28 1984 Date-Received: Sat, 17-Mar-84 02:37:29 EST References: <4076@edai.UUCP> Organization: Masscomp, Westford, MA Lines: 69 edai!ok cites section 7.4 of the "C Reference Manual" to show that subtraction of two pointers yields an int (not an integer, or a long, but explicitly an int). He is correct that the pointer result of pointer subtraction is a signed quantity (&p[0] - &p[0] should equal -1), but incorrectly asserts that the compiler should therefore require that no array contain more 32767 bytes (assuming 16-bit int's). Since pointer subtraction scales the result, the compiler would have to limit you 32767 elements in an array, since only pointer subtraction between two pointers in the same way is meaningful. This is clearly an undesirable restriction, but not any sillier than numerous machine architectures that make it difficult to have arbitrarily large arrays. The 8086 with 64K byte segments is one example of this. At the other extreme, the early Multics hardware (and as far as I know, the current hardware) limits segments to 256K words. Of course, like any good standard, the C reference manual says conflicting things about anything even remotely controversial. :-) Discussing pointers and integers in section 6.4: An integer or long integer may be added to or subtracted from a pointer; in such a case the first is converted as specified in the discussion of the addition operator. Two points to objects of the same type may be subtracted; in this case the result is converted to an integer as specified in the discussion of the subraction operator. This discussion occurs in section 7.4 (the discussion of subtraction was already quoted by edai!ok). It doesn't say what is supposed to happen if the value in a long cannot be represented as an int, so accepting long's in pointer addition may be just a courtesy measure to save the user from an explicit cast to int. Finally, in section 14.4 (Explicit poiner conversions) we find: A pointer may be converted to any of the integral types large enough to hold it. Whether an int or long is required is machine dependent. The mapping function is also machine dependent, but is intended to be unsurprising to those who know the addressing structure of the machine. Details for some particular machines are given below. This is a direct contradiction of edai!ok's claim, and is the paragraph normally used to justify e.g. 16 bit int's and 32-bit pointers. Since 14.4 is in conflict with 7.4, one or the other must be revised. I think most people would prefer to see 7.4 changed to make the result of pointer subtraction machine dependent. By the way, although I think edai!ok is wrong with respect to what is stated in the C reference manual, I absolutely agree that any compiler ought to make int's large enough to hold any pointer unless the performance penalties are prohibitive. Even though this assumption is not justified by the reference manual, it is made by too much C programs to change easily. This is why most C compilers for the Motorola 68000 use 32-bit int's even though using 16-bit int's would speed up most programs substantially (~ 50%, I think). In this case, portability wins out over efficiency. Besides, Motorola will be coming out with a 32-bit 68000 pretty soon, so why worry? :-) A third option was posted recently that I am sure has occurred to many people independently, namely have *two* compilers -- one with long int's for portability, and one with short int's for speed. -- Tom Teixeira, Massachusetts Computer Corporation. Westford MA ...!{ihnp4,harpo,decvax}!masscomp!tjt (617) 692-6200 x275