Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!blake!ogccse!schaefer From: schaefer@ogccse.ogc.edu (Barton E. Schaefer) Newsgroups: comp.lang.c Subject: Re: When is a cast not a cast? Message-ID: <2515@ogccse.ogc.edu> Date: 3 May 89 16:19:28 GMT References: <2747@buengc.BU.EDU> Reply-To: schaefer@ogccse.UUCP (Barton E. Schaefer) Organization: Oregon Graduate Center, Beaverton, OR Lines: 71 In article <2747@buengc.BU.EDU> bph@buengc.bu.edu (Blair P. Houghton) writes: } Here's one that popped up last night/this morning (keep that Sanka } away from me! %-S ) I think you've definitely had too much of it. :-) } I wanted to be a 'good little programmer' and make all the types } match up, so I was using casts wherever a promotion might be } non-obvious. In particular, I fell for: } } 3 char *c; } 4 char *p; } 5 int i; } 10 p = (c + (char *) i); /* More trouble than it's worth... */ } } wherupon both the lint(1) and cc(1) in my Ultrix 2.2 piped-up with } warnings that the 'operands of + have incompatible types' on line 10... } } How can two things explicitly identifiable as being the same type } (one by declaration, the other by that all-powerful fiat, the cast) } be suddenly 'incompatible'? That's because of the way pointer arithmetic is defined: pointer op integer yields pointer, where op is plus or minus pointer minus pointer yields integer See K&R I, p. 99, the last paragraph above section 5.5. Subtraction is the only operation allowed on two pointers. } Now, who is having the more serious problem with (reduntantly?) casting } i to be a char * before this addition: me, or the programmming tools } under Ultrix version 2.2? It's you, because the cast is neither redundant nor correct. } I have an inkling as to what I'm missing, but it makes little sense } regardless: It involves getting the integer quantity (i * sizeof(char *)) Actually, it would be sizeof(char) that you are interested in. But you are confused about how it gets involved in the computation. } which leaves one right back in the pigpen wondering how to cast this greater } integer as in } } p = (c + (char *)( i * sizeof(char *) ); When you write p = c + i; for any pointers p and c of the same type and any integer i, then i is automatically scaled by sizeof *c (e.g., if float *c, then sizeof(float)), so that the result of the pointer arithmetic is a pointer to a location i * sizeof(float) bytes after c. If we take float *p, *c; as an example, the "equivalent" operation is p = (float *) ((int)c + i * sizeof(float)); I put "equivalent" in quotes because because the (int)c cast is not well- defined in general, so the compiler will not usually implement pointer arithmetic in this way. It just happens to work on certain widely available machines with a linear address space and 32-bit pointers. :-) -- Bart Schaefer "And if you believe that, you'll believe anything." -- DangerMouse CSNET / Internet schaefer@cse.ogc.edu UUCP ...{sun,tektronix,verdix}!ogccse!schaefer