Используя макрос, мы можем создать генератор типов:
#define struct_entity(...) \
struct __VA_ARGS__ { \
int a; \
int b; \
}
Затем мы можем создать экземпляр этого типа в виде теговой или анонимной структуры по желанию:
struct_entity(entity);
struct player {
struct_entity();
const char *name;
};
int main() {
struct player player;
player.a = 1;
player.b = 2;
player.name = "bar";
}
ThisКод ближе к тому, что вы хотите, и не имеет проблемы UB с подходом объявления только элементов структуры в макросе .В частности, внутри struct player
есть элемент структуры, а не отдельные элементы.Это важно, потому что компилятор может выполнять уменьшение заполнения и переупорядочение элементов - особенно для встроенных целей.Например, composite_1
и composite_2
ниже не обязательно имеют одинаковое расположение!:
#include <assert.h>
#include <stddef.h>
typedef struct sub_1 {
int a;
void *b;
char c;
} sub_1;
typedef struct sub_2 {
void *d;
char e;
} sub_2;
typedef struct composite_1 {
int a;
void *b;
char c;
void *d;
char e;
} composite_1;
typedef struct composite_2 {
struct sub_1 one;
struct sub_2 two;
} composite_2;
// Some of the asserts below may fail on some architectures.
// The compile-time asserts are necessary to ensure that the two layouts are
// compatible.
static_assert(sizeof(composite_1) == sizeof(composite_2), "UB");
static_assert(offsetof(composite_1, a) == offsetof(composite_2, one.a), "UB");
static_assert(offsetof(composite_1, b) == offsetof(composite_2, one.b), "UB");
static_assert(offsetof(composite_1, c) == offsetof(composite_2, one.c), "UB");
static_assert(offsetof(composite_1, d) == offsetof(composite_2, two.d), "UB");
static_assert(offsetof(composite_1, e) == offsetof(composite_2, two.e), "UB");