Отличается между доступом к элементу структуры XX по базовому адресу + смещение XX и имя_структуры-> XX - PullRequest
1 голос
/ 22 июня 2011

Я использую библиотеку с открытым исходным кодом (Easy C State Machine). Когда я просматривал код, я обнаружил, что структура доступна по базовому адресу + смещение X, что-то вроде следующего.

#define OFF_SET_OF_XX 1
#define GET_MEMBER(X, Y, Z) ((X)(*((X*)(((int*)(Y))+Z))))

typedef struct Foo {
int i;
int XX;
}Foo;

Foo *foo1 = alloc(...);
int j = GET_MEMBER(int, foo1, OFF_SET_OF_XX);

вместо:

Foo *foo1 = alloc(...);
int j = foo1->XX;

Какая разница между двумя выше? Есть ли преимущество у первого?

Библиотека написана на ANSI C. Но сказано, что она может поддерживать только две архитектуры: x86 и amd64. Поскольку я хочу использовать его в другой арке, я просмотрел исходный код и обнаружил, что единственным кодом, связанным с архитектурой, является OFF_SET_OF_XXs.

Ответы [ 2 ]

2 голосов
/ 22 июня 2011

Прежде всего, я хотел бы отметить, что крайний левый тип для типа X не является необходимым, так что вы можете упростить его до:

#define GET_MEMBER(X, Y, Z) (*((X*)(((int*)(Y))+Z)))

Тем не менее, я не вижу цели использования такого макроса. Он отбрасывает безопасность типов, а синтаксис громоздок.

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

РЕДАКТИРОВАТЬ 1: Я предполагаю, что первоначальный автор библиотеки не знал о структурах и изобрел свою собственную вещь, похожую на структуры, используя alloc, указатели и макросы. Теперь, когда он сделал библиотеку открытым исходным кодом, другие пытаются преобразовать ее, чтобы использовать структуры, но есть много кода для преобразования, и они еще не закончили.

1 голос
/ 22 июня 2011

Самая близкая вещь, которую я видел с законной целью (пограничная, IMO), это макрос container_of ядра Linux.

Но для приведенного вами примера нет абсолютно никаких причинделайте это иначе, чем "автор дебил".Он ничего не выигрывает в производительности, жертвует удобочитаемостью и предлагает досадные ошибки (например, что произойдет, если кто-нибудь решит когда-нибудь изменить i на long)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...