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
tagas pointer touint32_t, then dereference it."