need help parse this difficult type

D

dillogimp

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.
 
I

Ian Collins

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);}
 
E

Eric Sosman

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*)'.
 
D

dillogimp

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 = va_arg(ap, obj *);
va_end(ap);
return ret;
}
 
E

Eric Sosman

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/>.
 
I

Ian Collins

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 = 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.
 
O

Old Wolf

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!)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top