В простом c у меня есть ситуация, когда я хотелось бы позволить функции принимать несколько типов указателей. Чтобы проиллюстрировать мою ситуацию, здесь может быть один вариант использования:
void myfunction([int* or char*] value) {
*value = 0xdd; // safe since value is at least as big as a char*
}
А вот еще:
#define MAGIC 0xabcdef0
typedef struct {
int magic;
char* content;
} MyStruct;
void myfunction([int* or MyStruct*] value) {
if (*value != MAGIC) {
printf("Got an int\n");
} else {
printf("Got a MyStruct\n");
}
}
// example:
int input1 = 0;
MyStruct input2 = { MAGIC, "hello world" };
myfunction(input1); // "Got an int"
myfunction(input2); // "Got a MyStruct"
Обе эти ситуации могут быть реализованы с помощью типа параметра void*
, но это фактически позволит передать любой тип указателя без ошибки компиляции. Есть ли способ ограничить функцию, чтобы она принимала только определенное подмножество типов указателей?
3 ответа
Если вы можете использовать новые функции C11, ключевое слово _Generic
может решить вашу проблему:
void myfunction(void *value) {
// ...
}
#define myfunction(x) myfunction( \
_Generic((x), char *: (x), int *: (x)) )
Вы могли сделать это:
void myfunction(void *s)
{
if ( *(int *)s == MAGIC )
{
MyStruct *p = s;
printf("%s\n", p->content);
}
}
Однако такой дизайн упрощает написание кода с ошибками, который компилятор не поймет за вас, поэтому я бы порекомендовал придумать немного другой дизайн (например, помеченные объединения).
Как указал Хоуман, вы можете использовать объединение для выполнения этой работы, однако у вас все еще есть проблема, заключающаяся в том, что вы должны определить тип, который установлен в типе объединения. Вы можете решить эту проблему, используя перечисление для определения типа внутри вашей функции.
union myUnion {
int* intPointer,
MyStruct* myStructPointer
};
enum typeEnum {
INT,
MYSTRUCT
};
void myfunction(union myUnion union, enum typeEnum type) {
if (type == INT)
// you got an integer
else if (type == MYSTRUCT)
// you got a struct
// You can add future additions here
}
Похожие вопросы
Связанные вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.