是否可以在C和/或C ++中为函数定义符号不明确的指针参数?
例如,假设我有一个函数可以同时处理8位变量的无符号和有符号类型,并且该函数采用指向要处理/操作的变量的指针。
我知道我可以使用(unsigned char *)或(signed char *)进行类型转换,但是我正在寻找更简洁的东西。
unsigned char Var1;
signed char Var2;
void MyFunction(unsigned char* Var);
MyFunction(&Var2); // This creates an error
话虽如此,我想提出一个想法,即我有一种语言,即高于汇编语言的语言不应使用BYTE / WORD / DWORD或QWORD之类的名称来定义具有显式符号类型的变量。我之所以这样说,是因为这些是用于组装的大小运算符,实际上并未定义符号。登录程序集由所选指令选择。但是我看到这些名称在C / C ++中随处可见,并且至少在Windows上定义为未命名。对我来说这似乎是利益冲突...
答案 0 :(得分:1)
如果两种对象的逻辑相同,则最好的选择是使用功能模板。
template <typename T>
void MyFunction(T* Var);
如果只想限制8位类型使用该功能,则可以在实现中使用static_assert
。
template <typename T>
void MyFunction(T* Var)
{
static_assert(sizeof(T) == 1, "Wrong type. Can only deal with 8-bit types.");
...
}
答案 1 :(得分:1)
使用C,您的选择有限。您可以在调用函数时进行不喜欢的类型转换:
void MyFunction(unsigned char* Var);
int main(void) {
unsigned char Var1 = 5U;
signed char Var2 = 5;
MyFunction(&Var1);
MyFunction((unsigned char *)&Var2);
}
您可以使用void *
并在函数本身中进行类型转换,而不必将错误的指针类型传递给它:
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
是其他任何东西,则它将无法编译,因为在通用关联列表中未考虑其他任何类型。