【问题标题】:Define sign ambiguous pointer parameter for a function为函数定义符号模糊指针参数
【发布时间】:2019-03-21 12:06:46
【问题描述】:

是否可以在 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++ 中随处使用,并被定义为 unsinged,至少在 Windows 上是这样。这对我来说似乎是一种利益冲突......

【问题讨论】:

  • 您知道void* 或模板吗?
  • 1.您的意思是“签名”而不是“签名”。 2. C 和 C++ 没有单独的有符号和无符号操作符,行为由类型决定。所以很自然,类型不仅仅是一个大小(如你所愿),而且还包含语义。
  • @Tas void* 用于删除所需的符号,但现在大小不明确。大小只能是 8 位,任何大小的变量都可以用 void* 传递。
  • 类型转换有什么不干净的地方?
  • @BenVoigt 我知道 C/C++ 没有单独的有符号和无符号操作运算符。阅读我帖子的最后一部分。

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


【解决方案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 是其他类型,它将无法编译,因为通用关联列表中没有其他类型。

【讨论】:

  • 谢谢!。 _Generic 方法可能是我在这些语言中得到的最接近的方法。
【解决方案2】:

如果两种对象的逻辑相同,最好的选择是使用函数模板。

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.");
   ...
}

【讨论】:

  • 嗯。是的,这可以工作,但不适用于我的特殊情况,因为该函数实际上是用汇编编写并用 C/C++ 声明并从那里调用的。
  • +1 为你投票,因为如果函数本身是用 C++ 编写的,你有一个答案会起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
相关资源
最近更新 更多