[comp.sys.m68k] C machine

andrew@teletron.UUCP (Andrew Scott) (01/01/88)

I've got a related question to this discussion thread; I've crossposted to
comp.sys.m68k also.

In article <9961@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> I would say that, if the machine has a 64 bit address space and 64
> bit arithmetic, but the `natural' arithmetic size is 32 bits, it
> is 32 bits; otherwise it is 64.  I would make longs 64 (or perhaps
> even 128) bits, and shorts quite possibly still 16 bits.  It would
> be nice to have 8, 16, 32, and 64 bit values, and it seems natural
> to make those `char', `short', `int', and `long' respectively.  This
> might be a problem for program that assume either short==int or
> long==int, though.

What should be the compiler writer's criteria for selecting the "natural"
size for the above C types?  Should it be bus size, internal register size,
or something else.  Our 68000 compiler has 16 bit shorts, 32 bit longs (which
make sense) and 32 bit ints (which doesn't always make sense).

A lot of code I've come across uses scratch variables (array indices etc.) of
type int.  Of course, 32 bit arithmetic must be used.  However, the 68000 has
16 bit divide and multiply instructions, which are *much* faster than the 
subroutine calls to the 32 bit arithmetic routines.  The case could be made
that a 16 bit quantity is the "natural" size for arithmetic operations for
the 68000.

Why would a compiler vendor for the 68000 choose a 32 bit size for an int?

	Andrew			(..alberta!teletron!andrew)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)

In article <166@teletron.UUCP> andrew@teletron.UUCP (Andrew Scott) writes:
>Why would a compiler vendor for the 68000 choose a 32 bit size for an int?

To make it easier to port sloppily-written VAX code.

chip@ateng.UUCP (Chip Salzenberg) (01/09/88)

Andrew Scott asks:
>Why would a compiler vendor for the 68000 choose a 32 bit size for an int?

To which Doug Gwyn replies:
>To make it easier to port sloppily-written VAX code.

Yes -- but not all compiler writers have buckled under the great mass of
"AllTheWorldsAVax" programs.  The most popular C compilers available for
the Commodore Amiga (Manx and Lattice) have different sizes for "int"!
One is 16 bits (int==short) and the other is 32 bits (int==long).

I prefer 16 bits myself, but that's a religious issue, and far be it from
me to start an argument.  :-)
-- 
Chip Salzenberg                 UUCP: "{codas,uunet}!ateng!chip"
A T Engineering                 My employer's opinions are a trade secret.
    "Anything that works is better than anything that doesn't."  -- me

cmcmanis%pepper@Sun.COM (Chuck McManis) (01/14/88)

In article <147@ateng.UUCP> chip@ateng.UUCP (Chip Salzenberg) writes:
> I prefer 16 bits myself, but that's a religious issue, and far be it from
> me to start an argument.  :-)

Certainly that is a valid preference :-). But on the subject, when I wrote
a BASIC interpreter for a Z80 (I know, this is comp.sys.m68k) I wrote it
using 32 bit ints even though I had to go to great pains to do so simply
because 32 bits were so much more useful than 16. I left 16 bit ints in
as 'shorts' because they were useful for things like array indices. 

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

johnf@apollo.uucp (John Francis) (01/15/88)

>Why would a compiler vendor for the 68000 choose a 32 bit size for an int?

Consider:

    main()
        {
        char    c[100000],p1,p2;
        int     dp;

        p1 = &c[0];
        p2 = &c[99999];

        dp = p2 - p1;
        }

The result of subtracting two pointers is *defined* (K&R) to yield
a result of type int. Not long int - int!  Any implementation that
can not represent this in an int is not an implementation of C.

Mind you, any decent 68000 compiler should provide a 16-bit short int,
and the code generator should be able to handle a = b + c (all shorts)
without converting b & c to ints, adding them, and then converting the
result to short.  If it is really good it should be able to do the same
for a = b + 2.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/15/88)

In article <39aca826.7f32@apollo.uucp> johnf@apollo.uucp (John Francis) writes:
>The result of subtracting two pointers is *defined* (K&R) to yield
>a result of type int.

That's another of the things that ANSI C intends to fix.

alex@umbc3.UMD.EDU (Alex S. Crain) (01/16/88)

In article <7092@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <39aca826.7f32@apollo.uucp> johnf@apollo.uucp (John Francis) writes:
>>The result of subtracting two pointers is *defined* (K&R) to yield
>>a result of type int.
>
>That's another of the things that ANSI C intends to fix.


Fix? How pray tell would you fix it? make it machine dependent? or just
arbitrary? 

	Pick one:

	Pntr - Pntr -> int
	Pntr - Pntr -> long int
	Pntr - Pntr -> Pntr      (This looks interesting ....)
	Pntr - Pntr -> NewAnsiTypeOfDuboiusValueFirstImplementedByBorland
	Pntr - Pntr -> ????

-- 
					:alex.

alex@umbc3.umd.edu

gwyn@brl-smoke.UUCP (01/16/88)

In article <708@umbc3.UMD.EDU> alex@umbc3.UMD.EDU (Alex S. Crain) writes:
>Fix? How pray tell would you fix it? make it machine dependent? or just
>arbitrary? 

It should be obvious what to do if you think about it.

First, only pointers into the same object can meaningfully be subtracted.
Second, the result of the subtraction necessarily has implementation-
defined signed integral type; there is a typedef ptrdiff_t in <stddef.h>.

alex@umbc3.UUCP (01/17/88)

In article <7109@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <708@umbc3.UMD.EDU> alex@umbc3.UMD.EDU (Alex S. Crain) writes:
>>Fix? How pray tell would you fix it? make it machine dependent? or just
>>arbitrary? 
>
>It should be obvious what to do if you think about it.
>
>First, only pointers into the same object can meaningfully be subtracted.
>Second, the result of the subtraction necessarily has implementation-
>defined signed integral type; there is a typedef ptrdiff_t in <stddef.h>.


	Hmm..

	I don't really understand the answer, I think you said "impementation
dependant". If so, how is that a fix? when I'm calculating offsets in a lisp
implementation, and I decide that the fastest way is to use the actual 
addresses and reletively reference functions, and i say 

	funcall (ptr1 - ptr2); /* ptr1 - ptr2 > 64k */

what happens? or do I just check stddef.h for the answer?

	I would prefer 32bit (or rather, the largest default integer available
including pointers) ints, because conversion to short int is absolutely 
painless (mov.l becomes mov.w) while conversion the other way can be a rather
serious problem.


-- 
					:alex.

alex@umbc3.umd.edu

levy@ttrdc.UUCP (Daniel R. Levy) (01/17/88)

In article <7092@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
#> In article <39aca826.7f32@apollo.uucp> johnf@apollo.uucp (John Francis) writes:
#> >The result of subtracting two pointers is *defined* (K&R) to yield
#> >a result of type int.
#> 
#> That's another of the things that ANSI C intends to fix.

ok, so what will the result be?  long??
-- 
|------------Dan Levy------------|  Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
|         an Engihacker @        |  	<most AT&T machines>}!ttrdc!ttrda!levy
| AT&T Computer Systems Division |  Disclaimer?  Huh?  What disclaimer???
|--------Skokie, Illinois--------|

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)

In article <712@umbc3.UMD.EDU> alex@umbc3.UMD.EDU (Alex S. Crain) writes:
>	I don't really understand the answer, I think you said "impementation
>dependant". If so, how is that a fix?

It *is* implementation-dependent, whether or not you like it that way.
The "fix" is to quit insisting that ptrdiff_t has to be int and to permit
it to be long where necessary.

> when ... i say 
>	funcall (ptr1 - ptr2); /* ptr1 - ptr2 > 64k */
>what happens? or do I just check stddef.h for the answer?

What do you mean, what happens?  You pass an argument having some signed
integral type to funcall().  Presumably you have properly declared
funcall() as in
	extern void funcall( ptrdiff_t );

If you don't like using a type other than a known basic type, you can of
course coerce the ptrdiff_t into a long via a (long) cast, but seldom is
this necessary or useful.  (It is necessary if you're going to printf()
the value of a ptrdiff_t.)

chip@ateng.UUCP (Chip Salzenberg) (01/20/88)

In the beginning, gwyn@brl.arpa (Doug Gwyn) wrote:
>First, only pointers into the same object can meaningfully be subtracted.
>Second, the result of the subtraction necessarily has implementation-
>defined signed integral type; there is a typedef ptrdiff_t in <stddef.h>.

Then alex@umbc3.UMD.EDU (Alex S. Crain) asks what dpANS says about code like:
>	funcall (ptr1 - ptr2); /* ptr1 - ptr2 > 64k */

The expression "ptr1 - ptr2" evaluates to an expression of the type
ptrdiff_t.  If you did your homework, then you defined the parameter to
funcall as a ptrdiff_t, so your stack will line up neatly.

But Doug did not mention whether ptrdiff_t is a signed or unsigned type.
Or is this not specified in dpANS?  When will I stop asking rhetorical
questions? :-)

>	I would prefer 32bit (or rather, the largest default integer available
>including pointers) ints, because conversion to short int is absolutely 
>painless (mov.l becomes mov.w) while conversion the other way can be a rather
>serious problem.

Conversion from 32 bits to 16 bits is painless, but for many architectures,
manipulation of 32-bit quantities is awkward and/or slow.  Thus X3J11 is
avoiding (whenever possible) giving minimum sizes for standard types.

Repeat after me:  "Not all C programs run on 32-bit architectures."
-- 
Chip Salzenberg                 UUCP: "{codas,uunet}!ateng!chip"
A T Engineering                 My employer's opinions are a trade secret.
       "Anything that works is better than anything that doesn't."

pablo@polygen.uucp (Pablo Halpern) (01/20/88)

In article <708@umbc3.UMD.EDU> alex@umbc3.UMD.EDU (Alex S. Crain) writes:
>>>The result of subtracting two pointers is *defined* (K&R) to yield
>>>a result of type int.
>>
>>That's another of the things that ANSI C intends to fix.
>
>
>Fix? How pray tell would you fix it? make it machine dependent? or just
>arbitrary? 

The ANSI Draft that I have (Oct 1, 1986) describes the header file <stddef.h>
which defines two types.  As quoted from the document:

	The types are

		ptrdiff_t

	which is the signed integral type of the result of subtracting
	two pointers; and

		size_t

	which is the unsigned integral type of the result of the sizeof
	operator.

(end quote)
A machine with a short word but long pointer type (e.g. 68000, 8086) would
have definitions like

	typedef long		ptrdiff_t;
	typedef unsigned long	size_t;

in <stddef.h>.  Machines with short pointers (e.g. 8080, 6502) would
have definitions like

	typedef int		ptrdiff_t;
	typedef unsigned	size_t;

or better yet

	typedef long		ptrdiff_t;
	typedef unsigned	size_t;

The reason for the long ptrdiff_t definition is that the difference
between two unsigned, 16-bit pointers can excede the -32768 - +32767
range of a 16-bit two's compliment signed integer.  Machines with long
words and long pointers could use any of the above pairs of
declarations.

So the short answer to the question is: the difference of two pointers
has a type that is machine (and compiler) dependent.  But this is no
worse (or better) than making the definition of an int machine dependent.

Pablo Hapern,  Polygen Corp.  UUCP: {bu-cs,princeton}!polygen!pablo

john@frog.UUCP (John Woods, Software) (01/20/88)

In article <147@ateng.UUCP>, chip@ateng.UUCP (Chip Salzenberg) writes:
> Andrew Scott asks:
> >Why would a compiler vendor for the 68000 choose a 32 bit size for an int?
> To which Doug Gwyn replies:
> >To make it easier to port sloppily-written VAX code.
> Yes -- but not all compiler writers have buckled under the great mass of
> "AllTheWorldsAVax" programs.

Well, now that you mention it:  CRDS has always used 32 bits for an int on
the 68000, largely because (a) the 68020 was promised to be "real" 32 bits
when it came out, and (b) the rest of the system we were designing was 32
bits (it just had this bottleneck at the CPU chip).  (These, plus a desire
for marketing hype, I suppose).

The MC68000 is closer to being a 32 bit machine than the PDP-11 was, even if
it lacked niceties like 32 bit multiply or divide.

--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw@eddie.mit.edu

"Cutting the space budget really restores my faith in humanity.  It
eliminates dreams, goals, and ideals and lets us get straight to the
business of hate, debauchery, and self-annihilation."
		-- Johnny Hart

alex@umbc3.UMD.EDU (Alex S. Crain) (01/20/88)

In article <155@ateng.UUCP> chip@ateng.UUCP (Chip Salzenberg) writes:
	[lots of stuff, and...]
>Repeat after me:  "Not all C programs run on 32-bit architectures."

	Correct. And I like the idea of a compiler that allows switchable
default int sizes, BUT...

	I still prefer 32 default ints to 16. Why? 
	1) because I do alot of stuff that wont fit in 16 bits.
	2) because of the way I write code, ie:
		a) block the project into little pieces.
		b) make each little piece work.
		c) rough tune the entire project.
		d) fine tune the little pieces.

There's more too it than that, but the order is about right. I've found
that no amount of preplaning will allow for the great idea that I get a 
4:45am 3 weeks into the project, and I don't want to be screwing around 
with size errors while I'm adding in what ever it is that I've forgotten.
Ie: I want the program to work now, it can work well later, if I have time.

	All in all, its a matter of preference. My code uses alot of
short ints, and thats fine with me. And I havn't heard any real good
reasons why ints should be 16 bits besides programmer preference. I've
gotten to the point where I prototype everything anyway, and I always
cruise through the final product looking for dead variables, etc, 
and scale everything down then. 

-- 
					:alex.

alex@umbc3.umd.edu

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/21/88)

In article <155@ateng.UUCP> chip@ateng.UUCP (Chip Salzenberg) writes:
>In the beginning, gwyn@brl.arpa (Doug Gwyn) wrote:
>>Second, the result of the subtraction necessarily has implementation-
>>defined signed integral type; there is a typedef ptrdiff_t in <stddef.h>.
          ^^^^^^
>But Doug did not mention whether ptrdiff_t is a signed or unsigned type.

See ^^^^^^ above.

>Repeat after me:  "Not all C programs run on 32-bit architectures."

That's for sure.  Some of mine run on 64-bit architectures.

gene@cooper.cooper.EDU (Gene (the Spook)) (01/23/88)

in article <7092@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) says:
> 
> In article <39aca826.7f32@apollo.uucp> johnf@apollo.uucp (John Francis) writes:
>>The result of subtracting two pointers is *defined* (K&R) to yield
>>a result of type int.
 
> That's another of the things that ANSI C intends to fix.

"Fix"? "FIX"???? Please! ANSI's done enough already. Why don't they just
leave it alone? After all, what else would it be?

Take the example of an offset from a pointer. If, for example, you have

		p1 = p0[d]

This would be interpreted as

		(ptr) p1 = (ptr) p0 + (int) d

Simply, add an integer displacement to a pointer, and you'll get another
pointer. With a little algebra, solve for 'd'. You'll get

		(int) d = (ptr) p1 - (ptr) p0

This is simply solving for the displacement. What else could it be???
I think the K&R solution is just fine the way it is. How in the world
could ANSI "fix" it? Can someone please explain that to me? Really, I
would appreciate an email'ed response, since I don't often get to read
the news. Thanx in advance.

					Spookfully yours,
					Gene

					...!ihnp4!philabs!phri!cooper!gene


	"If you think I'll sit around as the world goes by,
	 You're thinkin' like a fool 'cause it's case of do or die.
	 Out there is a fortune waitin' to be had.
	 You think I'll let it go? You're mad!
	 You got another thing comin'!"

			- Robert John Aurthur Halford

nevin1@ihlpf.ATT.COM (00704a-Liber) (01/28/88)

In article <1186@cooper.cooper.EDU> gene@cooper.cooper.EDU (Gene (the Spook)) writes:
.Take the example of an offset from a pointer. If, for example, you have
.
.		p1 = p0[d]
.
.This would be interpreted as
.
.		(ptr) p1 = (ptr) p0 + (int) d

Actually, I thought that 'p1 = p0[d]' is interpreted as

	(ptr) p1 = (ptr) p0 +  (long) (d * sizeof(type p0))

assuming long can hold all possible additions to pointers.

.Simply, add an integer displacement to a pointer, and you'll get another
.pointer. With a little algebra, solve for 'd'. You'll get
.
.		(int) d = (ptr) p1 - (ptr) p0
.
.This is simply solving for the displacement. What else could it be???

FIrst off, d should be a long, not an int.  A possibility for what d should be
is the value that makes p0[d] === p1.  (I am not suggesting that this happen)

.I think the K&R solution is just fine the way it is.

100% agreement here.
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/30/88)

In article <569@tuvie> rcvie@tuvie.UUCP (Alcatel-ELIN Forsch.z.) writes:
>Besides, subtraction of pointers should work for any two pointers, ...

Not feasible for segmented architectures.