Получение значения 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
тогда разыщите его."