C не поддерживает эту форму самоанализа типа.То, что вы спрашиваете, невозможно в C (по крайней мере, без специфичных для компилятора расширений; это возможно в C ++, однако).
В общем, с C вы должны знать типы вашей переменной.,Поскольку каждая функция имеет конкретные типы для своих параметров (за исключением, вероятно, varargs), вам не нужно проверять тело функции.Единственный оставшийся случай, который я вижу, - это тело макроса, и, ну, макросы C на самом деле не настолько мощны.
Кроме того, обратите внимание, что C не сохраняет никакой информации о типе во время выполнения.Это означает, что, даже если бы гипотетически существовало расширение сравнения типов, оно работало бы корректно только тогда, когда типы известны во время компиляции (т. Е. Не работало бы для проверки, указывают ли два void *
на один и тот же типdata).
Что касается typeof
: Во-первых, typeof
является расширением GCC.Это не стандартная часть C. Обычно она используется для написания макросов, которые оценивают свои аргументы только один раз, например (из руководства GCC ):
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
Ключевое слово typeof
позволяет макросу определять локальный временный объект для сохранения значений его аргументов, что позволяет оценивать их только один раз.
Короче говоря, C не поддерживает перегрузку;вам просто нужно набрать func_a(struct a *)
и func_b(struct b *)
и позвонить на правильный.Кроме того, вы можете создать свою собственную систему самоанализа:
struct my_header {
int type;
};
#define TYPE_A 0
#define TYPE_B 1
struct a {
struct my_header header;
/* ... */
};
struct b {
struct my_header header;
/* ... */
};
void func_a(struct a *p);
void func_b(struct b *p);
void func_switch(struct my_header *head);
#define func(p) func_switch( &(p)->header )
void func_switch(struct my_header *head) {
switch (head->type) {
case TYPE_A: func_a((struct a *)head); break;
case TYPE_B: func_b((struct b *)head); break;
default: assert( ("UNREACHABLE", 0) );
}
}
При создании этих объектов вы, конечно, должны не забывать правильно инициализировать заголовок.