Я ищу фрагмент кода, который может сказать мне смещение поля в структуре без выделения экземпляра структуры.
IE: дано
struct mstct {
int myfield;
int myfield2;
};
Я мог написать:
mstct thing;
printf("offset %lu\n", (unsigned long)(&thing.myfield2 - &thing));
И получите offset 4 на выходе. Как я могу это сделать без декларации / присвоения mstct thing?
Я знаю, что &<struct> не всегда указывает на первый байт первого поля структуры, я могу учесть это позже.





Как насчет стандартного макроса offsetof () (в stddef.h)?
Обновлено: для людей, у которых по какой-то причине может быть недоступен макрос offsetof (), вы можете получить эффект, используя что-то вроде:
#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field))
Вау - нет stddef.h? Могу я из любопытства спросить, что вы используете?
Он соответствует стандарту C99, поэтому я бы посоветовал приобрести новый компилятор.
более того - это было в C со времен ANSI C89. Я понятия не имею, насколько часто (или редко) это было до стандарта.
Однажды у меня был компилятор C, в котором смещение offsetof () было определено в stddef.h с помощью трюка с нулем, но он также не позволял использовать ноль в качестве базового адреса. (Давным-давно - 1989 г. или около того.) Вместо этого нужно было изменить 0 на 1024.
Правильно, используйте макрос offsetof, который (по крайней мере, с GNU CC) доступен как для кода C, так и для кода C++:
offsetof(struct mstct, myfield2)
offsetof () используется в стандарте C / C++ с момента выхода первого стандарта ANSI C89. Он должен быть у каждого компилятора, если вы не используете что-то действительно древнее. Даже тогда это можно было бы сколотить, используя уродливое приведение и арифметику указателей.
Согласен - я бы, скорее всего, предоставил фиктивный <stddef.h> для предоставления этих макросов. Plauger предоставляет «Стандартную библиотеку C», и это простой заголовок, если он не обязательно должен быть переносимым.
AFAIK, offsetof () не hing но уродливое приведение и арифметика указателя ... что-то вроде: #define offsetof (type, field) ((char *) & (((type *) 0) -> field) - (char * ) 0)
printf ("смещение:% d \ n", & ((mstct *) 0) -> myfield2);
Помимо того, что offsetof делает это более читаемым способом, вы обычно не можете распечатать ptrdiff_t с %d - в системах LP64 он слишком большой.
Не совсем то, что я хотел, потому что у меня нет stddef.h, но он отвечает на мой вопрос следующим образом: #define offsetof (TYPE, MEMBER) ((size_t) & ((TYPE *) 0) -> MEMBER)