GCC 给了我以下警告:
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 **
avoid **
被接受的地方。这些类型之间没有隐式转换,因为 avoid*
的大小和对齐方式可能与其他指针类型不同。
解决方案是使用中间体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!
然而,这个程序也可以通过引入一个中间体来工作(尽管结果可能只有在' 值小到可以存储在 a 中long
时才有意义)。long
short
嗯...我认为像这样的构造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;
}
所以结论是我们需要 void 指针 或 来确保数据的恒定性,但不能两者兼而有之。