limitations of casts, pointer and fu

jim at ISM780B.UUCP jim at ISM780B.UUCP
Sun Nov 4 03:37:30 AEST 1984


>{
>        int x;
>        char *y;
>/*### [cc] illegal lhs of assignment operator = %%%*/
>        (char *)x = y;
>}
>
>I don't think that this error message is sensible, since statments like
>
>*((long *) 100) = 100;
>
>work.

(char *)x is not an lvalue.  Use

	*(char **)&x = y;

if you must at all (better yet, learn to write type-strict code).

>I would like to declare a pointer to a thing of its own kind, i.e.
>something of the form:
>
>typedef ref *ref;
>
>The point is that if a pointer of this type is dereferenced, it should
>have the same type again.  In addition, the type should be cast'able
>to/from integer, and the size associated with it should be that of a
>single pointer of its kind.  I.e. expressions of the following type
>should be possible:
>
>{
>        ref a,b;
>        long c;
>        *a = b;
>        a = *b;
>        c = (int)a;
>        a = (ref)c;
>        a++;
>}
>
>My first attempt was:
>
>typedef long base;      /* change this to int type with size of pointer */
>typedef base *ref;
>#define deref(thing) ((ref)(*thing))
>
>This works fine if one does all dereferencing through 'deref',
>except that assignments still don't work quite right, since
>'deref(thing)=thing;' still does not work, and the rhs has to
>be cast instead (i.e. '*thing = (base)thing').

Forget it.  The best you can do is

typedef long ref;
#define mkref(x) (*(ref *)&(x))

{
	ref a,b;
	long c;
	mkref(*a) = b;
	a = mkref(*b);
	c = (int)a;
	a = mkref(c);
	a++;
}

which doesn't work if c is a register variable, except on some compilers
which allow *&x even if x isn't addressable.

>Along the same lines, I'd like to be able to define a function
>returning a pointer to its own kind, i.e.
>
>typedef fun (*fun)();
>
>which is useful to implement continuations without having to resort
>to machine language hacks.

No need to use machine language.  Try

#include <stdio.h>

typedef char *  funval;
typedef funval  (*funp)();

int     bluemoon = 7;

funval
fun(x)
{
	return x == bluemoon? NULL : (funval)fun;
}

funp    funv = fun;

main()
{
	register funp   funx;
	register        i;

	for( i = 0, funx = funv;; i++ )
	{   funx = (funp)(*funx)(i);
	    if( !funx ) break;
	}
	printf("%d\n", i);
}

-- Jim Balter, INTERACTIVE Systems (ima!jim)



More information about the Comp.lang.c mailing list