2017-01-06 9 views
1

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

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

/** 
* 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-битные беззнаковые int. Я хочу макрос, который, учитывая строку как аргумент, возвращает unsigned int. Я попытался

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

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

tag2uint("FREE") => 70 

который является код ASCII для ' F».

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

ответ

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

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

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

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

это означает, что «лечить tag как указатель на uint32_t, затем разыменования его.»