[comp.arch] Abusing pointers

drw@cullvax.UUCP (01/26/87)

In article <1029@cuuxb.UUCP>, mwm@cuuxb.UUCP (Marc W. Mengel) writes:
> Unfortunately, you don't have to take the address of a given variable
> to use it, you merely have to take the address of a variable near it
> and add an offset to it.  The way C is defined, this is quite legal.
> 
> For example, suppose I have a function f, declared as follows:
> 	f(p)
> 		struct { int a, b, c; } *p;
> 	{
> 	...
> 	}
> And I call it as follows:
> 	b()
> 	{
> 		int a, b, c;
> 
> 		f( &a );
> 	}
> According to our venerable friends kerningham&ritchie, this is legal;
> it is also used to some great extent in the older (v6 & v7) unix kernels.

1. Quite true, you don't have to have a pointer to a thing to mung it.
But if you want to use pointers in a portable way (i.e., ways that are
defined by the language, not by the implementation), the pointer you
start from and the thing that you manipulate must lie within the same
allocated thing, generally, either a declared object or malloc'ed
lump.  In particular, if you declare

	int a, b, c;

the implementation is not required to allocate a, b, and c one after
the other, nor to even allocate them the same way between different
compilations of the same code.  ("varargs.h" cheats in two ways:  (1)
it is implementation-dependent, and (2) since it is betting on the
relative locations of arguments (not auto's), and the argument-passing
format has to be predictable, it can figure out the offsets between
them.)

2. I doubt that there is an example of this silly usage in K&R, and I'm
certain that there is no clear statement that this is legitimate.

3. The mere fact that someone has made a mistake in using a language
(and gotten away with it) doesn't make it correct--the meaning of a
language is defined by the specification, not by the compiler.  (The
problem with standards is that there are too many cooks.)

4. As far as I know, the only cast between different pointer types
that is guaranteed to work is that you can cast a pointer to char *
and back, and it won't change.  If you want to turn structure pointers
into float *'s, ask the people on word-based machines.

Dale
-- 
Dale Worley		Cullinet Software
UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw
ARPA: cullvax!drw@eddie.mit.edu

michael@crlt.UUCP (02/20/87)

In article <1029@cuuxb.UUCP>, mwm@cuuxb.UUCP (Marc W. Mengel) writes:
+> Unfortunately, you don't have to take the address of a given variable
+> to use it, you merely have to take the address of a variable near it
+> and add an offset to it.  The way C is defined, this is quite legal.
+> 
+> For example, suppose I have a function f, declared as follows:
+> 	f(p)
+> 		struct { int a, b, c; } *p;
+> 	{
+> 	...
+> 	}
+> And I call it as follows:
+> 	b()
+> 	{
+> 		int a, b, c;
+> 
+> 		f( &a );
+> 	}
+> According to our venerable friends kerningham&ritchie, this is legal;
+> it is also used to some great extent in the older (v6 & v7) unix kernels.

I have heard that this is used in a number of kernels, and of course it
would work in a lot of compiler-generated code that didn't do tricks with
registers or storage allocation, and didn't waste a lot of processor and
programmer effort trying to "protect" you against your folly, but where
do K&R come out and say it is legal?  I just re-read the source I think
would be the most likely place (the "pointers" chapter of the sky-blue
C book) and didn't find it.

===========================================================================
  "I've got code in my node."	| UUCP:  ...!ihnp4!itivax!node!michael
				| AUDIO: (313) 973-8787
	Michael McClary		| SNAIL: 2091 Chalmers, Ann Arbor MI 48104
---------------------------------------------------------------------------
Above opinions are the official position of McClary Associates.  Customers
may have opinions of their own, which are given all the attention paid for.
===========================================================================

kaiser@uiucdcsp.UUCP (02/24/87)

Concerning some fancy pointer referencing stuff, michael@crlt.UUCP asks :

>I have heard that this is used in a number of kernels, and of course it
>would work in a lot of compiler-generated code that didn't do tricks with
>registers or storage allocation, and didn't waste a lot of processor and
>programmer effort trying to "protect" you against your folly, but where
>do K&R come out and say it is legal?  I just re-read the source I think
>would be the most likely place (the "pointers" chapter of the sky-blue
>C book) and didn't find it.

In section 14.1 of the K&R C Reference manual (Structures and Unions)
we find the loophole. In a reference to a structure, you are 
supposed to reference of of that structures components; but
"to allow an escape from the typing rules" (or perhaps to simplify
writing the early C compilers?) the restriction is not enforced.

The section is concluded with "Such constructions are non-portable.",
which pretty much summarizes it.  The compiler writer may take
poetic license with such strange constructs.

Roger Kaiser
uiucdcsp!kaiser