Доступ к полю структуры внутри другой структуры без ссылки на внутреннюю структуру - PullRequest
0 голосов
/ 17 декабря 2018

Предположим, у меня есть структура, которая определяется следующим образом:

struct entity {
    int x;
    int y;
};

И структура, которая использует ее в качестве члена:

struct player {
    struct entity position;
    char* name;
};

Если я напишу следующий код, тоЯ получаю сообщение об ошибке:

struct player p;
p.x = 0;         //error: 'struct player' has no member named 'x'

До сих пор я писал функцию, которая принимает структуру проигрывателя и возвращает значение, выполняя return player.position.x.

Есть ли компилятор?флаг, или другой метод, который позволяет мне "сгладить" (я не уверен, что это правильная фраза) структуру и позволяет мне получить доступ к переменной x, как я показал выше?Я понимаю, что это может быть неоднозначно, если внутри проигрывателя и сущности также есть целое число с именем x.

Обратите внимание, что я буду использовать структуру entity в нескольких структурах, и поэтому янельзя использовать анонимную структуру внутри player .

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Вы можете определить затем как MACRO:

#define ENTITY_MEMBERS int x; int y
struct entity{
    ENTITY_MEMBERS;
}

struct player {
    ENTITY_MEMBERS;
    char* name;
};

На самом деле, именно так вы имитируете одиночное наследование C ++ в C.

0 голосов
/ 17 декабря 2018

Используя макрос, мы можем создать генератор типов:

#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");
0 голосов
/ 17 декабря 2018

Короче говоря, ответ "Нет".Это особенно верно, если вы посмотрели на такие вопросы, как Какие анонимные структуры и союзы полезны в C11 и обнаружили, что они не являются решением.

Вы можете посмотреть на C11 §6.7.2.1 Спецификаторы структуры и объединения для получения дополнительной информации о структуре и типах объединения в целом (и ¶13 конкретно для получения дополнительной информации об анонимных членах, и ¶19 для примера).Я согласен, что они не то, что вы ищете;они включают новый определенный тип без тега и без «списка объявлений».

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