2010-05-12 4 views
1

Я в настоящее время просматриваю какой-то исходный код, который я нашел в сети, который использует макросы препроцессора таким образом, что я не понимаю. Он реализует четырехъядерную структуру данных. Надеюсь, что кто-то может прояснить мне все!Макросы препроцессора Не ​​понимаю

typedef int edge_ref; 

typedef struct { 
    edge_ref next[4]; 
    void *data[4]; 
    unsigned mark; 
} edge_struct; 

#define ROT(e) (((e)&0xfffffffcu)+(((e)+1)&3u)) 
#define SYM(e) (((e)&0xfffffffcu)+(((e)+2)&3u)) 
#define TOR(e) (((e)&0xfffffffcu)+(((e)+3)&3u)) 

#define ONEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[(e)&3] 
#define ROTRNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+1)&3] 
#define SYMDNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+2)&3] 
#define TORLNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+3)&3] 

#define MARK(e) ((edge_struct *)((e)&0xfffffffcu))->mark 

и это, как они используются:

edge_ref e; 
e = (edge_ref) malloc(sizeof(edge_struct)); 
ONEXT(e) = e; 
SYMDNEXT(e) = SYM(e); 
ROTRNEXT(e) = TOR(e); 
TORLNEXT(e) = ROT(e); 
MARK(e) = 0; 
return e; 

Это только отрывок обрисовать то, что у меня возникли проблемы с. Все можно найти: here

+5

мои глаза, они истекают кровью. Угадайте, что кто-то не сказал этому разработчику разницу между функциями и макросами. Пойдите, удалите того, кто написал это, это заставит вас чувствовать себя лучше. – wheaties

+0

Я думаю, что это очень оптимизированная по скорости реализация. – guest

+1

Есть ли что-то конкретное, что вы не понимаете (например, маскирование символов указателя edge_struct) или все это непостижимо? Ваш вопрос немного открыт. –

ответ

1

0xfffffffcu - это просто константа без знака со всеми битами, установленными в 1, за исключением последних 2 бит, которые равны 0, то есть 11111111111111111111111111111100. Он используется в качестве маски для манипуляции нижних двух бит e. Вся суть этих макросов, по-видимому, заключается в том, что вы можете работать с массивом из 4 структур, которые вы рассматриваете как круговой массив (например, по модулю 4).

+0

, что имеет смысл для меня сейчас, поскольку структура данных вызванный _quad_ edge – guest

2

Эти макросы - это простая замена кода. Что касается того, что происходит, это другое дело.

ONEXT(e) = e; 

становится ((edge_struct *) ((е) & 0xfffffffcu)) -> следующая [(е) & 3] = е;

Который выглядит так, как будто они загружают структуру с данными, связанными с адресом.

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

1

Подождите ...

typedef int edge_ref; 

#define ONEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[(e)&3] 

e = (edge_ref) malloc(sizeof(edge_struct)); 
ONEXT(e) = e; 

Возвращение таНоса отливают в знаковом междунар, который используется без проверки на NULL и маскируется с беззнаковым междунаром ...

I не знаю, для чего этот код, но я настоятельно рекомендую не использовать его для любых целей.

0

Я предполагаю, что они добавили теги к указателям, если они выровнены. (Вот почему маскируются операции перед разыменованием).

1

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

((edge_struct *)((e)&0xfffffffcu)) 

это так, edge_ref является указателем на объект типа edge_struct и индекс во внутренний массив объекта (e) & 3u бит).

Файл под: умный, но euurrgghh (рядом с XOR list).

+0

не будет ли этот подход также вызывать проблемы при работе на 64-битной ОС? – guest

+0

@guest: да, это сломается ужасно, так как вы потеряете верхние 32 бита адреса. Вы можете расширить версию 0xfffffffc до 64-битных версий. – Skizz

+0

thx для всех входных данных! пока не понял его полностью, но получил хорошее сцепление с тем, что происходит. – guest