ado@elsie.UUCP (Arthur David Olson) (06/29/86)
As I understand it, the code produced by some compilers from long x(cp) char * cp; { return *((long *) cp); } will cause core dumps if the value of cp isn't "appropriately aligned". When dealing with such compilers, you get to do something like long x(cp) char * cp; { long l; function_to_do_arbitrary_copying((char *) &l, cp, sizeof l); return l; } to avoid core dumps. Isn't this really a compiler bug? Doesn't the cast in the return *((long *) cp); give the compiler all the evidence it needs that it should, *on its own*, produce code that's the equivalent of the function call? Does the latest version of X3J11 have anything to say on the matter? -- Bug/s is a Volkswagen/Warner Brothers trademark. -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!ado@seismo.ARPA DEC, VAX, Elsie & Ado are Digital, Borden & Shakespeare trademarks.
chris@umcp-cs.UUCP (Chris Torek) (06/29/86)
In article <6152@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >As I understand it, the code produced by some compilers from > > long x(cp) > char * cp; > { > return *((long *) cp); > } > >will cause core dumps if the value of cp isn't "appropriately aligned". >... Doesn't the cast in the > return *((long *) cp); >give the compiler all the evidence it needs that it should, *on its own*, >produce code that's the equivalent of the function call? [\S = section symbol] No. K&R, Appendix A, \S 14.4, p.~210: 14.4 Explicit pointer conversions ... A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions upon use if the subject pointer does not refer to an object suitably aligned in storage. ... While you are verifying this, take a look at \S 16. I think it is amusing that as long ago as 1978, K&R identified most of the major portability problems that many people are now seeing for the first time. (The big one they left out of \S 16 is null-pointer derefer- encing.) You were warned, eight years ago! :-) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
ark@alice.UucP (Andrew Koenig) (06/29/86)
> Isn't this really a compiler bug? Doesn't the cast in the > return *((long *) cp); > give the compiler all the evidence it needs that it should, *on its own*, > produce code that's the equivalent of the function call? When you cast a pointer type to another pointer type, you have stepped outside the bounds of the language. The implementation is entitled to do as it pleases.
guy@sun.uucp (Guy Harris) (06/29/86)
> Isn't this really a compiler bug? Doesn't the cast in the > return *((long *) cp); > give the compiler all the evidence it needs that it should, *on its own*, > produce code that's the equivalent of the function call? A piece of software has a "bug" if it's supposed to do something and it doesn't; for instance, if it's supposed to generate correct code and it generates incorrect code instead. The C compiler isn't *supposed* to do unaligned copying in circumstances like this, so it can hardly be a "bug" if it doesn't. > Does the latest version of X3J11 have anything to say on the matter? The August 11, 1985 draft says: C.3.3.2 Address and indirection operators ... Semantics ... If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined. Such invalid values include ... *an address inappropriately aligned for the type of the object pointed to*... I *very* sincerely doubt this has been changed in any later drafts. Such dereferences are uncommon occurrences, and a programmer can damn well write their own code to do the unaligned copy. So a C compiler which doesn't generate unaligned copies is perfectly within its rights to do so, and has no bug. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)
john@frog.UUCP (John Woods, Software) (07/01/86)
> long x(cp) > char * cp; > {return *((long *) cp); } > will cause core dumps if the value of cp isn't "appropriately aligned". > When dealing with such compilers, you get to do something like > long x(cp) > char * cp; > { long l; > function_to_do_arbitrary_copying((char *) &l, cp, sizeof l) > return l; > } > to avoid core dumps. > Isn't this really a compiler bug? No, I'd say not. The compiler is doing just exactly what you said in the first case. What you said was something stupid, ergo it does something stupid. Lint will complain about the construction, declaring there to be a "possible pointer alignment problem" (you bet!). (by the way, an in-line copy would be faster than the function call (except perhaps on machines where function calls take negative time :-) )). -- John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101 ...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA "Imagine if every Thursday your shoes exploded if you tied them the usual way. This happens to us all the time with computers, and nobody thinks of complaining." Jeff Raskin, interviewed in Doctor Dobb's Journal
kab@reed.UUCP (Kent Black) (07/03/86)
In article <6152@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >As I understand it, the code produced by some compilers from > > long x(cp) > char * cp; > { > return *((long *) cp); > } > >will cause core dumps if the value of cp isn't "appropriately aligned". > >Isn't this really a compiler bug? Doesn't the cast in the > return *((long *) cp); >give the compiler all the evidence it needs that it should, *on its own*, >produce code that's the equivalent of the function call? Oh, am I in over my head. . . If a (char *) can reference any `byte' of memory, and a (long *) can can only reference, as example, even number word addresses, then to have the compiler correctly cast a char * to a long * would mean it rearranged your data for you. In particular, an array of characters would have to be remade into an array of longs with the apropriate (high or low) byte holding the character. Is this all wrong? But do you *really want* to cast a char pointer to a long pointer just to dereference and return the value? The example seems to instead call for dereferencing the char * and casting the value as a long, e.g., return (long) *cp; I only respond because I'm not certain myself and would like some further discussion. Kent Black
friesen@psivax.UUCP (07/10/86)
In article <3783@reed.UUCP> kab@reed.UUCP (Kent Black) writes: > >Oh, am I in over my head. . . > >If a (char *) can reference any `byte' of memory, and a (long *) can >can only reference, as example, even number word addresses, then to have >the compiler correctly cast a char * to a long * would mean it rearranged >your data for you. In particular, an array of characters would have to >be remade into an array of longs with the apropriate (high or low) byte >holding the character. Is this all wrong? Yes, the purpose of the cast is to allow you to look at your array of char(or whatever) *as if* it were an array of longs. It would defeat the purpose of the cast if the compiler rearranged the memory for you! > >But do you *really want* to cast a char pointer to a long pointer just >to dereference and return the value? The example seems to instead call >for dereferencing the char * and casting the value as a long, e.g., > return (long) *cp; > No, this does something completely different. This reads a single byte from memory, *extends* it to a long and returns the result. On the other hand return *(long *)cp; reads a long from memory and returns it. That is it sort of acts like a union and allows you to look at the same piece of memory as having different types. -- Sarima (Stanley Friesen) UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen ARPA: ??