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