双指针转换,使用`const void ** ptr`参数传递给函数

时间:2012-09-27 12:14:18

标签: c pointers gcc

海湾合作委员会给了我以下警告:

note: expected 'const void **' but argument is of type 'const struct auth **

是否有可能导致问题的情况?

更大的代码段是

struct auth *current;
gl_list_iterator_next(&it, &current, NULL);

函数只存储在current一些void *指针中。

2 个答案:

答案 0 :(得分:7)

错误消息足够清楚:您正在传递struct auth **,其中void **被接受。这些类型之间没有隐式转换,因为void*可能与其他指针类型的大小和对齐方式不同。

解决方案是使用中间void*

void *current_void;
struct auth *current;

gl_list_iterator_next(&it, &current_void, NULL);
current = current_void;

编辑:为了解决以下评论,以下是为什么这是必要的示例。假设您在sizeof(struct auth*) == sizeof(short) == 2的平台上,而sizeof(void*) == sizeof(long) == 4;这是C标准所允许的,实际上存在具有不同指针大小的平台。然后OP的代码类似于做

short current;
long *p = (long *)(&current);  // cast added, similar to casting to void**

// now call a function that does writes to *p, as in
*p = 0xDEADBEEF;               // undefined behavior!

但是,也可以通过引入中间long来使该程序工作(尽管结果可能仅在long的值足够小以存储在{{1}时才有意义。 }})。

答案 1 :(得分:0)

嗯......我认为像const void *这样的结构没有多大意义。

因为如果用户想要访问void *下的数据,他需要从void转换,并且此操作会绕过编译器类型检查,从而绕过常量。

考虑这个例子:

#include <stdio.h>
#include <stdlib.h>

int main () {

  int i = 6;
  int * pi = &i;

  const void * pcv = pi;
  const int  * pci = pi;

  // casting avoids type checker, so constantness is irrelevant here
  *(int *)pcv = 7;

  // here we don't need casting, and thus compiler is able to guard read-only data
  *pci = 7;

  return 0;
}

所以结论是我们需要无效指针或确保数据的恒定性,但不是两者都是。