When is a cast not a cast?
Barton E. Schaefer
schaefer at ogccse.ogc.edu
Thu May 4 02:19:28 AEST 1989
In article <2747 at buengc.BU.EDU> bph at 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 at cse.ogc.edu
UUCP ...{sun,tektronix,verdix}!ogccse!schaefer
More information about the Comp.lang.c
mailing list