为函数定义符号歧义指针参数

时间:2018-10-16 21:25:06

标签: c++ c visual-studio visual-studio-2012 programming-languages

是否可以在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上定义为未命名。对我来说这似乎是利益冲突...

2 个答案:

答案 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来工作,它允许一种多态形式根据控制表达式的类型使用不同的表达式。在这种情况下,如果Xchar *signed char *,它将对unsigned char *进行类型转换。如果X已经是unsigned char *,它将保持原样。如果X是其他任何东西,则它将无法编译,因为在通用关联列表中未考虑其他任何类型。