Briefly, my problem is: I'm building a dynamic memory manager, which contains various different kinds of objects. I'm marking each different kind of object with a tag, and, to make memory debugging easier, I want those tags to appear in memory as four-byte strings of stuff I can read. However, to efficiently switch on those values, I also want to consider them as unsigned 32 bit integers.
Currently the definition of the objects looks like this:
/**
* an object in cons space.
*/
struct cons_space_object {
char tag[TAGLENGTH]; /* the tag (type) of this cell */
uint32_t count; /* the count of the number of references to this cell */
struct cons_pointer access; /* cons pointer to the access control list of this cell */
union {
/* if tag == CONSTAG */
struct cons_payload cons;
/* if tag == FREETAG */
struct free_payload free;
/* if tag == INTEGERTAG */
struct integer_payload integer;
/* if tag == NILTAG; we'll treat the special cell NIL as just a cons */
struct cons_payload nil;
/* if tag == REALTAG */
struct real_payload real;
/* if tag == STRINGTAG */
struct string_payload string;
/* if tag == TRUETAG; we'll treat the special cell T as just a cons */
struct cons_payload t;
} payload;
};
Tags are four character string constants, e.g.:
#define CONSTAG "CONS"
What I want to be able to so is something like
switch ( cell.tag) {
case CONSTAG : dosomethingwithacons( cell);
break;
But of course you can't switch on a string. However, as these are four byte strings, they could be read in memory as 32 bit unsigned ints. What I want is a macro which, given a string as argument, returns an unsigned int. I've tried
/**
* a macro to convert a tag into a number
*/
#define tag2uint(tag) ((uint32_t)*tag)
but what it in fact does is return as a number the ASCII value of the first character at that address - that is,
tag2uint("FREE") => 70
which is the ascii code for 'F'.
Anyone solve this for me? It's twenty years since I wrote anything serious in C.
means "dereference
tag
(get'F'
in your example), then convert it touint32_t
."What you want to do should be
this means "treat
tag
as pointer touint32_t
, then dereference it."