双指针转换,使用`const void ** ptr`参数传递给函数
海湾合作委员会给了我以下警告:
note: expected 'const void **' but argument is of type 'const struct auth **
有没有可能导致问题的情况?
更大的片段是
struct auth *current; gl_list_iterator_next(&it, ¤t, NULL);
函数只存储在current
一些void *
指针中。
错误消息足够清楚:您正在传递struct auth **
,其中接受了void **
。 这些类型之间没有隐式转换,因为void*
可能与其他指针类型的大小和对齐方式不同。
解决方案是使用中间void*
:
void *current_void; struct auth *current; gl_list_iterator_next(&it, ¤t_void, NULL); current = current_void;
编辑 :为了解决下面的评论,这里有一个为什么这是必要的例子。 假设你在sizeof(struct auth*) == sizeof(short) == 2
,而sizeof(void*) == sizeof(long) == 4
; 这是C标准所允许的,实际上存在具有不同指针大小的平台。 那么OP的代码将类似于做
short current; long *p = (long *)(¤t); // cast added, similar to casting to void** // now call a function that does writes to *p, as in *p = 0xDEADBEEF; // undefined behavior!
然而,这个程序也可以通过引入一个中间long
来工作(虽然结果可能只有当long
的值小到足以存储时才有意义)。
嗯……我认为像const void *
这样的结构没有多大意义。
因为如果用户想要访问void *
下的数据,他需要从void转换,并且此操作会绕过编译器类型检查,从而绕过 – 恒定。
考虑这个例子:
#include #include 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; }
所以结论是我们需要void指针或者确保数据的恒定性,而不是两者。