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