Смотрел тут давеча: http://www.wasm.ru/forum/index.php?action=vthread&forum=24&topic=5505&page=1 Там макрос есть странный. #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) Как понимаю я. Сначала ptr приводится указателю на char. Берётся ноль и проводится к указателю на тип type. Затем адрес этого преобразованного нуля рассматривается как указатель на структуру типа type. Т.е ноль - это адрес структуры с типом type. Теперь берётся из этой структуры член member приводится к unsigned long и отнимается от преобразованного в самом начале ptr. Результат приводится к указателю на тип type. Непонятно вот что, на какой экземпляр структуры будет указывать преобразованный 0(здесь я вообще теряюсь в догадках) и зачем приводится например ptr к указателю на char? Какая разница на что указывает указатель, его размер всё равно же будет 32 двоичных разряда для IA32. Короче в целом получается белеберда, и чёт я ни чё не пойму.
letopisec &((type *)0)->member Это просто смещение поля member относительно начала структуры. Если member - первое поле, то данное выражение будет равно нулю. Да, но то, что вычитается из указателя C умножает на размер типа указателя, т.е. (short int*) увеличит разницу в 2 раза, а (int*) в 4. Например: Код (Text): char *c; (int*)c + 1 равносильно c + 4
char *c; (int*)c + 1 равносильно c + 4 Ага. Понятно. Т.е прибавление к указателю 1, имеет не буквальное значение, а "укажи на следующий обьект". Это просто смещение поля member относительно начала структуры. Если member - первое поле, то данное выражение будет равно нулю. Т.е как будто по адресу = 0, находится структура, и мы находим абсолютный адрес её члена member. А так как адрес начала структуры - 0, то абсолютный и относительный адрес для member будет один и тот же. Так да?