如何在编译器检查以确保传递的参数是指向指针的指针时,如何正确消除此警告?
void somefunc (void **elements)
{
// This function works on any array type
// Maybe it prints pointer addresses
void **pp;
for (pp = elements; *pp; pp ++)
printf ("address: %x\n", *pp);
}
int main (const char *cmdline)
{
typedef struct {
int a, b, c;
} any_struct_t;
any_struct_t *group[25] = {0}; // (any_struct_t **)
group[0] = malloc (sizeof(any_struct_t));
somefunc(group); // <--- WARNING (any_struct_t **) vs. (void **)
getchar ();
exit (0);
}
是否有&#34; double void&#34; 类型的指针或一些超级模糊的C技巧,可以在这里正确使用它来正确摆脱此警告:
I want this warning to go away via code:
warning: passing argument 1 of 'somefunc' from incompatible pointer type
expected 'void **' but argument is of type 'any_struct_t **'
该函数需要一个指向指针的指针,它并不关心它是什么类型的指针。
我可以通过强制转换为(void *)来消除警告,但编译器不再检查它是否是指向指针的指针。
答案 0 :(得分:1)
void*
是唯一的通用指针类型,每个其他指针类型都可以隐式转换为/。这不适用于void**
,因为正式void**
不需要与x**
具有相同的实现。
但是,正如您所指出的,您只需转发到void*
,警告就会消失。从理论上讲,这不是便携式的。在实践中,我非常怀疑你这样做会遇到任何问题。
因此,如果你顽固地担心类型安全,那么你不会只是转向void*
并继续前进的唯一原因。如果你是,你应该编写一个函数来处理每个单独的指针类型。
例如,在C11中,您可以使用_Generic
关键字优雅地执行此操作:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a, b, c;
} any_struct_t;
#define some_func(ptr) \
_Generic( (ptr), \
any_struct_t**: some_any_struct)(ptr)
void some_any_struct (any_struct_t** pp)
{
for(; *pp != NULL; pp++)
{
printf ("address: %p\n", (void*)*pp);
}
}
int main(void)
{
any_struct_t* array [4] = {0};
array[0] = malloc(10*sizeof(any_struct_t));
array[1] = malloc( 1*sizeof(any_struct_t));
array[2] = malloc( 5*sizeof(any_struct_t));
array[3] = NULL;
some_func(array);
void* void_array[3];
some_func(void_array); // will cause compiler error, because void** is not supported
}
答案 1 :(得分:0)
如果传递的参数不是(至少)指向指针的指针,则至少会产生编译时错误。它并不完全是主意,但至少有类型检查。
void _somefunc (void **elements)
{
// This function works on any array type
// Maybe it prints pointer addresses
void **pp;
for (pp = elements; *pp; pp ++)
printf ("address: %p\n", *pp);
}
// ENSURE AT LEAST A POINTER TO A POINTER IN DEBUG BUILDS, WILL CAUSE ERROR IF NOT.
// error: invalid type argument of unary '*'
#ifdef DEBUG
// Ensure at least a pointer to a pointer. Compile-time error if not.
#define somefunc(x) _somefunc ((void **)x + sizeof(**x) - sizeof(**x))
#else
#define somefunc(x) _somefunc (((void **)x) // No warnings in release
#endif
答案 2 :(得分:0)
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
'dbs.options' => array (
'mysql_read' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_read.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8mb4',
),
'mysql_write' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_write.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8mb4',
),
),
));
}