получить имя typedef в C?

Я пишу большой код, в котором мне нужно ввести множество структур, а затем использовать указатели void на переменные этих структур, например:

typedef struct {
    int age;
    double height;
}human_t;

а затем я объявлю и инициализирую переменную типа: "human_t"

human_t peter = {
    21,
    1.95 };

тогда я сделаю пустой указатель на Питера:

void* ptr = &peter;

позже мне нужно знать, что «ptr» - это указатель на переменную типа «human_t». Как я могу это сделать ? есть ли какой-то предопределенный метод в C? извините за мое незнание :) еще новичок.


person yaboty    schedule 27.05.2014    source источник
comment
Вы не сможете этого сделать, если сами не сохраните где-нибудь эту информацию. Как правило, в C. нет скрытых вещей. Если у вас есть void*, это все, что у вас есть.   -  person n. 1.8e9-where's-my-share m.    schedule 27.05.2014
comment
Не очень актуально, но обратите внимание, что суффикс _t зарезервирован для типов posix   -  person David Ranieri    schedule 27.05.2014


Ответы (2)


Нет, «из коробки» это невозможно.

Это потребовало бы, чтобы информация о типе времени выполнения была каким-то образом связана с указателем, а этого просто не существует. Указатель void - это адрес памяти и не более того.

Конечно, вы можете, как и многие вещи, существующие на языках более высокого уровня, реализовать это самостоятельно.

В этом случае вы можете потребовать, чтобы каждый поддерживаемый struct начинался с enum, указывающего его тип. Затем вы можете преобразовать указатель на структуру в указатель на это перечисление, прочитать его значение, а затем узнать, с каким типом вы имеете дело:

typedef enum {
  ObjectType_Human,
  ObjectType_Alien,
  ObjectType_Predator,
  ObjectType_Smurf,
} ObjectType;

typedef struct {
  ObjectType type;
  int age;
  char name[32];
} human;

Тогда вы сможете:

void print_name(const void *obj)
{
  const ObjectType *tp = obj; /* No cast required! */
  switch(*tp)
  {
  case ObjectType_Human:
    printf("the human is called %s\n", ((human *) obj)->name);
    break;
  /* and so on ... */
  }
}

Вы также можете, например, поместить информацию о типе в карту, хешировав значение указателя.

Есть много подходов; вам нужно будет проанализировать и выбрать лучший для вашего конкретного приложения.

person unwind    schedule 27.05.2014

Увы, это непросто реализовать на C.

Один из подходов - стандартизировать ваши структуры так, чтобы первый элемент был полем типа.

Стандарт C гарантирует, что адрес структуры всегда выровнен по адресу первого элемента (то есть перед первым членом структуры нет заполнения). Поэтому безопасно сначала преобразовать void* в поле типа и, в зависимости от этого результата, преобразовать в структуру по вашему выбору.

person Bathsheba    schedule 27.05.2014
comment
большие пальцы руки вверх, чтобы догадаться, я напечатаю кастинг позже :) - person yaboty; 27.05.2014