Article 1358 of comp.bugs.4bsd: Path: haven!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.bugs.4bsd Subject: Re: Ultrix CC bug? Message-ID: <19626@mimsy.UUCP> Date: 16 Sep 89 20:19:22 GMT References: <199@infovax.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 74 In article dupuy@cs.columbia.edu (Alexander Dupuy) writes: >... [a] big-endian machine ... allows easy and graceful punning from >pointer type to pointer type, even if you bend the rules of C. >... a little-endian machine [does not] This is false, and indeed exactly backwards. Both machines allow easy puns from one pointer type to another, because all pointer types have the same size and format. But only little-endian machines can get away with puns on data types. (A type pun is a `conversion' that consists of simply pretending a variable has a new type. C compilers can use puns if it generates correct machine code using fewer instructions than would a true conversion.) >[on a VAX] pointers to ints, shorts and chars all point to the high >order byte No, pointers point to the numerically lowest byte, which, on a VAX, is least significant byte. On a 680x0, it is the most significant byte. We have to use the `Chinese writing method' to avoid confusion: location: byte: 000c 12 000d 34 000e 56 000f 78 Value at location 000c: type: on vax: on 680x0: char 12 12 short 3412 1234 long 78563412 12345678 In expressions like `*(long *)p', both machines simply `fetch a longword from the address', without really caring what was originally stored at that address. The trick comes in dealing with extended and narrowed objects. In C, parameters to (non-prototyped) functions are widened, so that `char' and `short' both become `int'. On a VAX, when one writes f(x) char x; { char *p = &x; ... } one gets a pun from the actual parameter (which has been `sent in' on the stack as an int) to the desired parameter (a char), while on the 680x0, one gets a conversion. In code: _f: .word 0 # (vax) # ap+4 points to one longword holding the widened value of x # in memory we have (if x=='!'): # # 4(ap) 21 # 5(ap) 00 # 6(ap) 00 # 7(ap) 00 # movab 4(ap),r0 # p = &x but _f: link a6,#0 | a6+8 points to one longword holding the widened value of x | in memory we have (if x=='!'): | | a6@(8) 00 | a6@(9) 00 | a6@(0a) 00 | a6@(0b) 21 | lea a6@(0b),a0 | p = &x which (inside the compiler) required a conversion to go from `a6@(8)' to `a6@(b)'. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris