469,658 Members | 1,862 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,658 developers. It's quick & easy.

need help parse this difficult type

hi

This code is taken from a lisp interpreter by Andru Luvisi.

typedef struct obj {
enum otype type;
struct obj *p[1]; // array of pointer, sizeof(obj)=8
} obj;
typedef obj * (*primop)(obj *);
obj *all_symbols, *top_env, *nil, *tee, *quote,
*s_if, *s_lambda, *s_define, *s_setb;

Can someone explain what is "typedef obj * (*primop)(obj *);"?
The subsequent line is for a bunch of pointers to "obj" that I
understand.
I understand "typedef" is like alias.
"typedef a b" is like "b is of an alias for a"
The way the code is written, I can't tell what is being aliased.
"(*)" usually means pointer to function that I understand,
My guess is:
// primop is a pointer to a function that takes (obj*) and returns
"obj*"

If that is correct, what is being aliased? Thanks.

Mar 5 '07 #1
6 1563
di*******@yahoo.com wrote:
hi

This code is taken from a lisp interpreter by Andru Luvisi.

typedef struct obj {
enum otype type;
struct obj *p[1]; // array of pointer, sizeof(obj)=8
} obj;
typedef obj * (*primop)(obj *);
My guess is:
// primop is a pointer to a function that takes (obj*) and returns
"obj*"

If that is correct, what is being aliased? Thanks.
Good guess!

"primop someFn" can be used as a shorthand for "obj* (*someFn)(obj*)"
wherever a function with this signature is required, for example in
function parameters or as structure members.

So

obj* foo( obj* (*someFn)(obj*), obj* object ) { return someFn(object);}

can be written

obj* foo( primop someFn, obj* object) { return someFn(object);}

--
Ian Collins.
Mar 5 '07 #2
di*******@yahoo.com wrote On 03/05/07 16:01,:
hi

This code is taken from a lisp interpreter by Andru Luvisi.

typedef struct obj {
enum otype type;
struct obj *p[1]; // array of pointer, sizeof(obj)=8
} obj;
typedef obj * (*primop)(obj *);
obj *all_symbols, *top_env, *nil, *tee, *quote,
*s_if, *s_lambda, *s_define, *s_setb;

Can someone explain what is "typedef obj * (*primop)(obj *);"?
The subsequent line is for a bunch of pointers to "obj" that I
understand.
I understand "typedef" is like alias.
"typedef a b" is like "b is of an alias for a"
The way the code is written, I can't tell what is being aliased.
"(*)" usually means pointer to function that I understand,
My guess is:
// primop is a pointer to a function that takes (obj*) and returns
"obj*"
Correct.
If that is correct, what is being aliased? Thanks.
`primop' is an alias for the type `obj* (*)(obj*)'.
Since `obj' is also an alias, the "full" type is
`struct obj* (*)(struct obj*)'.

--
Er*********@sun.com
Mar 5 '07 #3
On Mar 6, 5:01 am, dillog...@yahoo.com wrote:
hi

This code is taken from a lisp interpreter by Andru Luvisi.

typedef struct obj {
enum otype type;
struct obj *p[1]; // array of pointer, sizeof(obj)=8} obj;

typedef obj * (*primop)(obj *);
obj *all_symbols, *top_env, *nil, *tee, *quote,
*s_if, *s_lambda, *s_define, *s_setb;

Can someone explain what is "typedef obj * (*primop)(obj *);"?
The subsequent line is for a bunch of pointers to "obj" that I
understand.
I understand "typedef" is like alias.
"typedef a b" is like "b is of an alias for a"
The way the code is written, I can't tell what is being aliased.
"(*)" usually means pointer to function that I understand,
My guess is:
// primop is a pointer to a function that takes (obj*) and returns
"obj*"

If that is correct, what is being aliased? Thanks.

One more question: "struct obj *p[1]" "p" is array (1 element) of
pointer to "obj" right? The subsequent usage in the code make me doubt
that, because I see usage like :
#define car(X) ((X)->p[0])
#define cdr(X) ((X)->p[1])
....
#define procenv(X) ((X)->p[2])

wouldn't p[1] seg fault right away? I don't see ways to expand an
array in c language. (malloc is different, we can't assume p[1] is
located immediately after p[0], if p[1] is somehow malloc'ed. I just
can't see how p[1] or p[2] can be used syntax -wise in any fashsion.
Thanks. (the obj creation code follows.)

obj *omake(enum otype type, int count, ...) {
obj *ret;
va_list ap;
int i;
va_start(ap, count);
ret = (obj *) malloc(sizeof(obj) + (count - 1)*sizeof(obj *));
ret->type = type;
for(i = 0; i < count; i++) ret->p[i] = va_arg(ap, obj *);
va_end(ap);
return ret;
}

Mar 5 '07 #4
di*******@yahoo.com wrote On 03/05/07 16:17,:
On Mar 6, 5:01 am, dillog...@yahoo.com wrote:
>>hi

This code is taken from a lisp interpreter by Andru Luvisi.

typedef struct obj {
enum otype type;
struct obj *p[1]; // array of pointer, sizeof(obj)=8} obj;

typedef obj * (*primop)(obj *);
obj *all_symbols, *top_env, *nil, *tee, *quote,
*s_if, *s_lambda, *s_define, *s_setb;

Can someone explain what is "typedef obj * (*primop)(obj *);"?
The subsequent line is for a bunch of pointers to "obj" that I
understand.
I understand "typedef" is like alias.
"typedef a b" is like "b is of an alias for a"
The way the code is written, I can't tell what is being aliased.
"(*)" usually means pointer to function that I understand,
My guess is:
// primop is a pointer to a function that takes (obj*) and returns
"obj*"

If that is correct, what is being aliased? Thanks.

One more question: "struct obj *p[1]" "p" is array (1 element) of
pointer to "obj" right? The subsequent usage in the code make me doubt
that, because I see usage like :
#define car(X) ((X)->p[0])
#define cdr(X) ((X)->p[1])
...
#define procenv(X) ((X)->p[2])

wouldn't p[1] seg fault right away? [...]
This is Question 2.6 in the comp.lang.c Frequently Asked
Questions (FAQ) list at <http://www.c-faq.com/>.

--
Er*********@sun.com
Mar 5 '07 #5
di*******@yahoo.com wrote:
>
One more question: "struct obj *p[1]" "p" is array (1 element) of
pointer to "obj" right? The subsequent usage in the code make me doubt
that, because I see usage like :
#define car(X) ((X)->p[0])
#define cdr(X) ((X)->p[1])
....
#define procenv(X) ((X)->p[2])

wouldn't p[1] seg fault right away? I don't see ways to expand an
array in c language. (malloc is different, we can't assume p[1] is
located immediately after p[0], if p[1] is somehow malloc'ed. I just
can't see how p[1] or p[2] can be used syntax -wise in any fashsion.
Thanks. (the obj creation code follows.)

obj *omake(enum otype type, int count, ...) {
obj *ret;
va_list ap;
int i;
va_start(ap, count);
ret = (obj *) malloc(sizeof(obj) + (count - 1)*sizeof(obj *));
ret->type = type;
for(i = 0; i < count; i++) ret->p[i] = va_arg(ap, obj *);
va_end(ap);
return ret;
}
The form struct "obj *p[1]" is a common kludge where the actual number
of objects varies between object types. As you can see in the create
code, space is reserved for the required number of obj* and they are
initialised form the variable argument list, so they can be safely accessed.

--
Ian Collins.
Mar 5 '07 #6
On Mar 6, 10:01 am, dillog...@yahoo.com wrote:
>
typedef obj * (*primop)(obj *);

I understand "typedef" is like alias.
"typedef a b" is like "b is of an alias for a"
A good way of reading typedefs is to first drop the keyword 'typedef':

obj * (*primo)(obj *);

This declares an object named 'primo'. Now, the effect of the
typedef will be to declare a type name 'primop' that aliases
the type of 'primo'. (This is easier to understand than write!)

Mar 5 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Bill Borg | last post: by
10 posts views Thread by Tomás | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.