【问题标题】:void pointer in function call in C++ vs CC++ 与 C 中函数调用中的 void 指针
【发布时间】:2017-08-27 19:37:46
【问题描述】:

我有这段代码可以在 C 中运行,但不能在 C++ 中运行,有什么方法可以让它同时在 C 和 C++ 上运行吗?

void foo(void* b)
{
   int *c = b;
   printf("%d\n",*c); 

}

int main ()
{
 int a = 1000;

 foo(&a);
 return 0;
}

输出:

C++:

1 In function 'void foo(void*)':
2 Line 3: error: invalid conversion from 'void*' to 'int*'
3 compilation terminated due to -Wfatal-errors.

C:

1000

请帮忙

【问题讨论】:

  • int *c = static_cast<int*>(b);
  • 您可以将其从 void* 显式转换为 int* ,但这在 C 中是不必要的。
  • C 和 C++ 是不同的 编程语言。为什么您希望能够编写相同的代码在两者上运行?
  • 请注意(即使使用强制转换),如果您传递一个最初不是 int * 的指针(或多或少),这将导致静默的未定义行为
  • 您的 C 代码中还有一个(静默)错误(不了解 C++)。在范围内没有原型的情况下调用接受可变数量参数 (printf) 的函数会调用 未定义的行为。提高编译器的警告级别并注意警告!

标签: c++ c void-pointers


【解决方案1】:

void*int* 的无效转换

为了将void* 转换为int*,您需要在将b 分配给c 时将其转换为int*。做:

int *c = (int*) b;

这适用于 C++ 和 C。

【讨论】:

  • 对于 OP @HenriMenke 来说还是必要的。他想要 C/C++ 兼容的代码。加 1 票。
  • @HenriMenke 感谢您指出这一点!会的,请稍等。
  • 不要@ABusyProgrammer。 OP 专门说“有什么方法可以让它同时在 C 和 C++ 上运行吗?”...
  • 抱歉,@user54264611634646244 赶时间了,我正要通知 Henri 这个问题。这个演员表对 C++ 来说不是最好的,但它与两种语言都兼容,正如问题所问的那样:)
  • @David C. Rankin:这段代码显然是为了作为一个实验,旨在针对这个非常具体的功能:与void *指针之间的转换。
【解决方案2】:

C 允许在 void* 和任何指向对象类型的指针之间进行隐式转换,而 C++ 则不允许。要使您的代码与两种语言兼容,您可以输入foo( (void*)&a );

但是,在这两种语言中都不鼓励使用 void 指针 - 它们只能作为最后的手段使用。如果您希望该函数在 C 中是类型通用的,则可以使用 _Generic 关键字。在 C++ 中,您将使用模板。

【讨论】:

    【解决方案3】:

    考虑到这两种语言的所有转换问题,正确的方法是 -

    #ifdef __cplusplus
    #define cast_to_intp(x) static_cast<int*>(x)
    #else
    #define cast_to_intp(x) (x)
    #endif
    

    然后使用

    int *c = cast_to_intp(b);
    

    【讨论】:

    • static_cast&lt;int&gt; 是一个明显的错字。关于固有的不安全演员表,这就是这里所要求的。我不明白如何绕过它。我们可以假设 OP 知道他在做什么并适当地使用演员表。
    • @AnT 你认为哪个部分不会编译?
    • void * 转换为其他指针类型本质上是不安全的。而static_cast 无法提高这个演员的安全性。以上只会用不必要的预处理器分支和宏名称使代码变得毫无意义。那么,这实现了什么呢?
    • 如果用户已确定强制转换是正确的(使用包含类型的枚举或类似的其他参数,在这种情况下不是,因为这只是一个实验设置),强制转换将注意安全。演员的行为将被完全定义。
    • 我的问题是:那么你的宏的意义何在?与简单的int *c = (int *) b; 相比,它在两种语言中都有效吗? (您仍然缺少#endif,顺便说一句)。
    猜你喜欢
    • 2015-04-18
    • 2018-04-19
    • 1970-01-01
    • 2021-01-15
    • 2012-02-26
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多