Предположим, что у меня есть структура и извлечение смещения для члена:
struct A {
int x;
};
size_t xoff = offsetof(A, x);
Как я могу, указав указатель на struct A
извлечь элемент стандартным образом? Предполагая, конечно, что у нас есть правильный struct A*
и правильное смещение. Одна попытка - сделать что-то вроде:
int getint(struct A* base, size_t off) {
return *(int*)((char*)base + off);
}
Скорее всего, это сработает, но обратите внимание, например, что указатель-арифметика только кажется определенным в стандарте, если указатели являются указателями одного и того же массива (или одного конца), это не обязательно. Таким образом, технически эта конструкция, похоже, полагается на поведение undefined.
Другим подходом будет
int getint(struct A* base, size_t off) {
return *(int*)((uintptr_t)base + off);
}
который также, вероятно, сработает, но обратите внимание, что intptr_t
не требуется, чтобы существовать, и насколько я знаю, арифметика на intptr_t
не должна давать правильный результат (например, я помню, какой-то процессор имеет возможность для обработки не-байтовых выровненных адресов, которые предполагают, что intptr_t
увеличивается с шагом по 8 для каждого char
в массиве).
Похоже на что-то забытое в стандарте (или что-то, что я пропустил).