Как я могу получить тип объекта в коде? - PullRequest
0 голосов
/ 09 января 2012

Как мне определить тип объекта в C? Моя цель в этом состоит в том, чтобы создать контейнер связанных списков в C.

Предположим, у меня есть функция, которая принимает пустой указатель:

...
Foo *f;
f = Allocate(f);
...

void *Allocate(void *item)
{
  return malloc(sizeof(f.GetType));
}

Как сделать возможным приведенный выше синтаксис?

Ответы [ 6 ]

2 голосов
/ 09 января 2012

В C нет кроссплатформенного способа узнать базовый тип void *, так как информация о типе не сохраняется в объекте. В C ++ эта функция была добавлена ​​для объектов.

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

2 голосов
/ 09 января 2012

Это невозможно. void * указатель, это просто указатель на память, больше ничего, никакой дополнительной информации к нему не прикреплено. Невозможно сделать то, что вы просите, вы не можете знать, сколько байтов до malloc.

Именно поэтому функция qsort из библиотеки stdlib.h принимает в качестве параметра size в байтах каждого элемента массива. Если то, что вы предложили, было возможно, тогда qsort такой параметр не нужен.

Возможно, вы могли бы сделать что-то вроде этого:

...
Foo *f;
f = Allocate(f, sizeof(Foo));
...

void *Allocate(void *item, size_t size)
{
  return malloc(size);
}
1 голос
/ 09 января 2012
void *Allocate(void *item)
{
  return malloc(sizeof(f.GetType));
}

Это невозможно. Язык ISO C не предоставляет никаких средств для получения информации о типе через переменную. Расширения Gcc содержат оператор typeof, он может получить информацию о типе из реального типа. такие как:

typeof (x[0](1))
int a; typeof (a) b; b = a;

но даже если typeof также не смог получить информацию о реальном типе из указателя void. код ниже не может быть скомпилирован успешно:

void *Allocate(typeof(*item) *item)
{
  return malloc(sizeof(*item));
}
1 голос
/ 09 января 2012

(Спорная) красота C в том, что он этого не делает. Пустой указатель - это просто адрес, который может указывать на что угодно . Вы можете создать свою собственную объектную систему (структуры с полями типа и поля данных являются простым способом). Из вашей реализации также может быть возможно вставить функцию allocate в структуру Foo (при условии, что она есть), которая знает, как распределить себя (тип известен здесь).

1 голос
/ 09 января 2012

Единственный способ сделать это в C - это создать собственную систему типов, в которой вы включаете typeinfo в создаваемые вами типы. Это то, что было сделано, например, в Objective-C. В C все типы - это просто серия байтов, когда вы выделяете память, вы выделяете только байты, для чего вы используете эти байты, это не имеет значения для компилятора C.

1 голос
/ 09 января 2012

Просто невозможно получить type, используя void * к этому объекту. Если вы можете вычислить размер Foo перед вызовом Allocate(), тогда получите размер и передайте его в качестве параметра Allocate(), иначе вы должны сделать Foo видимым внутри Allocate(), чтобы найти размер.

...