繁体   English   中英

在ANSI-C中,void **是可接受的类型吗?

[英]Is void** an acceptable type in ANSI-C?

我看过一个函数的原型是:

int myfunc(void** ppt)

在C文件中,此函数称为= myfunc(mystruct ** var1);

其中mystruct是我们拥有的结构之一的typedef。

这在MSVC6.0中没有任何编译错误的情况下有效,但是当我使用其他C编译器对其进行编译时,它在使用错误消息调用此函数的位置给出了错误消息:

mystruct **类型的参数与void **类型的参数不兼容

myfunc()的参数保持为void **,因为它似乎是通用的malloc类型的函数,将使用各种结构变量类型来调用该函数以进行内存分配

  1. C标准/任何C编译器中是否有诸如void **之类的类型?
  2. 我该如何解决? [我尝试将函数调用参数强制转换为mystruct** ,但这没有用]

-广告

comp.lang.c FAQ问题4.9中详细解决了此问题。 简而言之,他们说将任意的指针对指针强制转换为void ** 并不严格可移植 他们接着解释说“这样的代码可能会起作用,有时建议这样做,但是它依赖于具有相同内部表示形式的所有指针类型(这是通用的,但不是通用的)”。 他们继续解释说,“您使用的任何void **值都必须是某个地方的实际void *值的地址; (void **)&dp ,尽管它们可能会关闭编译器,但它们是不可移植的(并且可能不是甚至做你想做的事。”

因此,您可以使用以下代码安全/便捷地实现所需的行为:

some_type *var1 = foo();
void *tmp_void_ptr = (void *)var1;
myfunc(&tmp_void_ptr);

void** 有效的,但是根据您的错误消息,您可能必须如下显式转换参数:

mystruct **var1;
x = myfunc ((void**) var1);

这是因为myfunc函数期望使用void**类型。 虽然可以将void*隐式转换为任何其他指针,但对于双指针则不是这样-您需要显式转换它。

编译器无法自动将mystruct**void**是有原因的。

考虑以下代码:

void stupid(struct mystruct **a, struct myotherstruct **b)
{
    void **x = (void **)a;
    *x = *b;
}

编译器不会抱怨*x = *b行中从myotherstruct*隐式myotherstruct*void* ,即使该行试图将指向myotherstruct的指针放在仅应放置指向mystruct指针的位置。

错误实际上是在上一行中,该行将“指向可以放置指向mystruct的指针的地方的指针”转换为“指向可以放置指向任何物的指针的地方的指针”。 就是没有隐式强制转换的原因。 当然,当您使用显式强制转换时,编译器会假定您知道自己在做什么。

这个问题有点令人困惑。 但是,是的, void **当然是合法有效的C,并且按预期表示“指向void指针”。

我不确定您的通话示例,参数(“ mystruct ** var1”)没有意义。 如果var1的类型为mystruct ** ,则该调用应仅读取a = func(var1); mystruct ** ,这可能是一个错字。

强制转换应该可以,但是您需要强制转换为void ** ,因为这是函数所期望的。

看起来很脏:有时候,如果不使用void **,就无法解决问题。

是的, void **是完全可以接受的,并且在某些情况下非常有用。 还要考虑给定的声明void **foovoid *bar ,编译器将知道foo指向的对象的大小(它指向一个指针,除了在一些您需要的古老平台上,所有指针的大小都相同)不必担心),但是它不会知道bar指向的对象的大小(它可以指向任何大小的对象)。 因此,您可以安全地对void **指针执行指针算术运算,但不能void *指针执行指针算术运算。 您必须先将它们转换为其他char * ,例如char * GCC允许您假装void *char *是等效的,每个指向一个对象的大小为单个字节,但这是非标准且不可移植的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM