Получение значения C-байтовой строки в виде uint

Вкратце, моя проблема заключается в следующем: я создаю динамический менеджер памяти, который содержит различные типы объектов. Я помечаю каждый объект различного типа тегом, и, чтобы упростить отладку памяти, я хочу, чтобы эти теги появлялись в памяти как четырехбайтовые строки, которые я могу прочитать. Однако для эффективного переключения этих значений я также хочу рассматривать их как 32-разрядные целые числа без знака.

В настоящее время определение объектов выглядит следующим образом:

/**
 * 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;
};

Теги - это четырехсимвольные строковые константы, например:

#define CONSTAG  "CONS"

То, что я хочу иметь, так это что-то вроде

switch ( cell.tag) {
  case CONSTAG : dosomethingwithacons( cell);
  break;

Но, конечно, вы не можете включить строку. Однако, так как это четыре байтовые строки, они могут быть прочитаны в памяти как 32-разрядные целые числа без знака. То, что я хочу, это макрос, который, учитывая строку в качестве аргумента, возвращает беззнаковое целое. я пробовал

/**
 * a macro to convert a tag into a number
 */
#define tag2uint(tag) ((uint32_t)*tag)

но на самом деле он возвращает в качестве числа значение ASCII первого символа по этому адресу, то есть

tag2uint("FREE") => 70

который является кодом ASCII для "F".

Кто-нибудь решит это для меня? Прошло двадцать лет с тех пор, как я написал что-то серьезное на C.

1 ответ

#define tag2uint(tag) ((uint32_t)*tag)

означает "разыменование" tag (получить 'F' в вашем примере), а затем преобразовать его в uint32_t".

То, что вы хотите сделать, должно быть

#define tag2uint(tag) (*(uint32_t*)tag)

это значит "лечить tag как указатель на uint32_tтогда разыщите его."

Другие вопросы по тегам