When is a cast not a cast?

Wm. E. Davidsen Jr davidsen at steinmetz.ge.com
Tue May 2 23:08:38 AEST 1989


In article <2747 at buengc.BU.EDU> bph at buengc.bu.edu (Blair P. Houghton) writes:

| 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:  (the line numbers are shown
| only for reference)
| 
| 1   main()
| 2   {
| 3	char *c;
| 4	char *p;
| 5	int i;
| 6	...
| 7	c = "somestring";  /* Nothing fancy, null-terminated. */
| 8	i = 4;  /* For example. */
| 9	...
| 10 	p = (c + (char *) i);  /* More trouble than it's worth... */
| 11	...
| 12  }
| 
| 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...

  C allows expressions involving a pointer and an int. The expression
	ptr + int
has the same type as ptr, and the address "ptr plus (int times the size
of the base type of ptr). The following expressions refer to the same
location, using the declarations at the start of the example:
	/* declare */
	int *ptr;	/* this is our pointer */
	int m;		/* this is the int we add */
	int *value;	/* this holds the resulting address */

	/* these result in the same value */
	value = (ptr + m);	/* parens optional */
	value = &ptr[m];
	value = &m[ptr];	/* ugly and confusing, but legal */

  In addition to the result of adding (or subtracting) an int and
pointer, the result of subtracting two pointers is an int, the number of
items of the base type of the pointers, subject to the following:
	a) the pointers must be of the same type
	b) the pointers must be into the same data structure
	   or the results will not be portable (and may not
	   work at all in some implementations).

  For example:
	int p[20], *ptr1, *ptr2, value;

	ptr1 = &p[0];
	ptr2 = &p[4];
	value = ptr2 - ptr1;	/* always 4 */

  regardless of the sizeof(int), the resul;t is four, because it is the
*number of items* of the base type between the pointers. Changing the
'int' type to any other type, including struct and union types, will not
effect the value of the subtraction. This eliminates some of the address
arithmetic tricks required by older languages.

  The reason that you are getting errors is that you are trying to add
two pointers, which is not a defined operation. Looking at your original
code again,

| 10 	p = (c + (char *) i);  /* More trouble than it's worth... */

what you want is just
	p = c + i;		/* no trouble at all */

Hope I made this clear, it's harder to understand once you learn it
wrong... I'm sure the usual people who respond to every question will
reply to this one.
-- 
	bill davidsen		(wedu at crd.GE.COM)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me



More information about the Comp.lang.c mailing list