С C у вас есть ограниченные возможности.При вызове функции вы можете выполнять приведение типов, которое вам не нравится:
void MyFunction(unsigned char* Var);
int main(void) {
unsigned char Var1 = 5U;
signed char Var2 = 5;
MyFunction(&Var1);
MyFunction((unsigned char *)&Var2);
}
, вы можете использовать void *
и typecast в самой функции и просто не передавать неверный тип указателя на нее:
void MyFunction(void* Var);
int main(void) {
unsigned char Var1 = 5U;
signed char Var2 = 5;
MyFunction(&Var1);
MyFunction(&Var2);
}
Или, если вы действительно хотите чего-то сверх этого, вы можете использовать макрос _Generic, чтобы автоматически настроить его для вас.Это может быть или не быть «лучшим» подходом, но я думаю, что он достигнет вашей цели.
#define MY_FUNCTION_HELPER(X) MyFunction( _Generic((X), \
char *: (unsigned char *)X, \
signed char *: (unsigned char *)X, \
unsigned char *: X \
) \
)
void MyFunction(unsigned char *Var);
int main(void) {
unsigned char Var1 = 5U;
signed char Var2 = 5;
MY_FUNCTION_HELPER(&Var1);
MY_FUNCTION_HELPER(&Var2);
}
Последний работает с использованием введенного C11 _Generic
, который позволяет форме полиморфизмаиспользовать разные выражения в зависимости от типа управляющего выражения.В этом случае, если X
равно char *
или signed char *
, он выполнит приведение типа к unsigned char *
.Если X
уже unsigned char *
, оно останется таковым.Если X
- это что-то еще, он не сможет скомпилироваться, так как никакие другие типы не учитываются в общем списке ассоциаций.