четверг, 25 июня 2009 г.

нечто очевидное

typedef struct some_struct
{
int dummy;
unsigned long long some_field[];
} some_type;

int main() {
int buf;
buf = (int)&((some_type*)0)->some_field[0];
printf("buf = (int)&((some_type*)0)->some_field[0];\n");
printf("sizeof(unsigned long long): %d, sizeof(int): %d, \
sizeof(some_type): %d\n",
sizeof(unsigned long long), sizeof(int),
sizeof(some_type));
printf("buf: %d\n\n", buf);

buf = (int)&((some_type*)0)->some_field[1];
printf("buf = (int)&((some_type*)0)->some_field[1];\n");
printf("sizeof(unsigned long long): %d, sizeof(int): %d, \
sizeof(some_type): %d\n",
sizeof(unsigned long long), sizeof(int),
sizeof(some_type));
printf("buf: %d\n\n", buf);

}


1. (some_type*)0 создали на стеке некий объект и преобразовали его к типу "указатель на структуру some_type". Т.о. по адресу памяти, на который указывает (some_type*)0 будет находится некий мусор, но память будет выделена;

[#########################################################]
[|########################################################]

2. ((some_type*)0)->some_field[1] тут произошло смещение на 1 позицию размером в sizeof(typeof(some_field));

[#########################################################]
[#################################|#######################]

3. &((some_type*)0)->some_field[1] взяли адрес полученной ячейки памяти. Фактически, уже тут мы получаем искомое - объем занимаемой памяти;

4. (int)&((some_type*)0)->some_field[1] компилятор перестал ругаться;

Вуаля, в выражении
(int)&((some_type*)0)->some_field[0]
нам не нужно знать типы структур и полей, чтобы вычислить размер памяти.

Комментариев нет:

Отправить комментарий