C 与 C++,处理 void** 指针
C vs. C++, handling of void** pointers
我发现使用 C 编译器,下面的代码可以工作,但不适用于C++编译器。我知道转换为void**
是正确的用法,但我不明白为什么即使我使用void*
C 编译器(注释掉(,它也使用 C 编译器编译。
#include <stdio.h>
int fn(void **arg)
{
int *pvalue = *(int**)arg;
*pvalue = 200;
return 0;
}
int main()
{
int value = 99;
int *pvalue = &value;
// fn((void *)&pvalue); // works only in C
// error C2664: 'int fn(void **)': cannot convert argument 1 from 'void *' to 'void **'
fn((void **)&pvalue); // correct, works for both C/C++
printf("%d", value);
return 0;
}
有人可以解释为什么会这样吗?
在 C 中,允许将类型void *
的指针分配给其他类型的指针。这发生在这次通话中
fn((void *)&pvalue)
其中参数具有分配给类型为void **
的函数参数的类型void *
。
int fn(void **arg)
{
int *pvalue = *(int**)arg;
*pvalue = 200;
return 0;
}
但是,这种分配通常是不安全的。例如,无法正确对齐 void * 类型的指针的值以分配给其他类型的指针。
因此,决定不允许在C++进行此类分配以使程序更安全。
我不明白为什么即使我使用 void*(注释掉(,它也使用 C 编译器编译。
它之所以编译,是因为void*
可以隐式转换为 C 中的其他指针。
fn((void **)&pvalue); // correct, works for both C/C++
由于强制转换,这可能是格式良好的,但该标准在技术上并没有明确保证转换为void**
和返回会产生相同的地址。
虽然这在实践中可能有效,但没有理由不使用void*
作为函数参数,这确实有保证。作为奖励,您不需要通话中的演员。喜欢这个:
int fn(void *arg);
fn(&pvalue); // correct, works for both C/C++
当然,这是假设首先需要类型擦除。避免在不需要时void*
。
为免生疑问,没有任何正确的内容
fn((void **)&pvalue);
它和
fn((void *)&pvalue);
使用 API 的正确方法是执行
int fn(void **arg)
{
int *pvalue = (int *)*arg;
*(int *)pvalue = 200;
return 0;
}
或
int fn(void **arg)
{
*(int *)*arg = 200;
return 0;
}
跟
int main()
{
int value = 99;
void *pvalue = (void*)&value;
fn(&pvalue);
printf("%d", value);
return 0;
}
不允许使用声明类型、兼容类型或字符类型以外的任何其他指针类型访问对象。此外,虽然void *
在 C 中用作指向各种对象的通用指针类型,但在 C 中没有指向指针类型的通用指针 - 除了void *
!
这就是为什么void **
几乎总是API中设计错误的标志 - 大多数用法都是错误的。
相关文章:
- 如何在 C++ 中将 void 函数传递给 void 指针
- 将通用引用强制转换为可调用的 void 指针,反之亦然
- C++为 void 指针分配一个字符串
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 取消引用 void 指针以将值分配给结构
- C 与 C++,处理 void** 指针
- 除了调用全局删除运算符之外,删除一个void指针还能做什么呢
- 用非零值初始化void指针的正确(或最安全)方法
- 将 void 指针分配给另一个 void 指针
- c ++ 我是否需要手动删除指向另一个具体类型的 void* 指针?
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 如何将 std::string 赋回作为 <char>void* 指针传递的 std::vector.data()?
- 将指针传递到结构,与传递 void 指针并强制转换为结构
- 如何在void*指针下检查运行时类型(允许简单类型,没有基类)?
- 用于初始化结构的 void 指针强制转换
- 使用 void 指针:void **ptr.. 如何修改共享内存的值?
- 访问由 void 指针引用的结构的成员
- 你不能在 void 指针上使用指针算法,那么 void 指针数组是如何工作的呢?
- 如何警告 C 中 void 指针上的参数不兼容的类型
- 指向类模板方法的 void 指针的向量