Martin Buchholz <martin(a)xemacs.org> writes:
[My first post seems missing from the list. Sorry if you see this twice]
I'd like you to prove me wrong - in this case I would support
the
permanent switch to C++.
Here is something I prepared earlier (ahem). All these structs would
be typedef'ed in a real use of course. I think you can do this
checking as long as you allow about 6 or so different types that under
C would all just be the same thing.
g++ -c gcpro.C
gcpro.C: In function `void incorrect()':
gcpro.C:74: conversion from `rv_lispobj' to non-scalar type `funarg_lispobj'
requested
Here is gcpro.C
typedef unsigned int lispobj_internal;
struct funarg_lispobj;
struct stack_lispobj;
/* Function returnvalues */
struct rv_lispobj {
lispobj_internal i;
// Here would come contructurs from most lisp_obj
};
struct ungcable_lispobj {
lispobj_internal i;
ungcable_lispobj(unsigned int in)
{
i = in;
};
private:
ungcable_lispobj();
};
/* Function arguments for functions that cannot GC */
struct nogcarg_lispobj {
lispobj_internal i;
nogcarg_lispobj(const struct ungcable_lispobj in);
nogcarg_lispobj(const struct funarg_lispobj in);
nogcarg_lispobj(const struct stack_lispobj in);
nogcarg_lispobj(const struct rv_lispobj in);
};
struct funarg_lispobj {
lispobj_internal i;
funarg_lispobj(const struct stack_lispobj in); // Would check in.gcprod_flag
// Note the missing contructor from rv_lispobj;
// Note the missing contructor from nogcarg_lispobj;
};
struct stack_lispobj {
lispobj_internal i;
bool gcpro_flag;
stack_lispobj()
{
gcpro_flag = false;
};
stack_lispobj(const struct rv_lispobj in)
{
i = in.i;
};
};
struct ungcable_lispobj zero(0);
struct rv_lispobj Fcons(struct nogcarg_lispobj car,
struct nogcarg_lispobj cdr);
// Can GC
struct rv_lispobj bar(struct funarg_lispobj arg);
void correct1()
{
stack_lispobj obj = Fcons(zero,zero);
obj.gcpro_flag = true; // Would be part of GCPRO;
bar(obj);
}
void correct2()
{
Fcons(Fcons(zero,zero),zero);
}
void incorrect()
{
bar(Fcons(zero,zero));
}