Инициализация void *b = a;
недопустима C, она нарушает правило простого присваивания C17 6.5.16.1 (инициализация следует правилам присваивания), в котором говорится, что для того, чтобы выражение было действительным:
... тип, на который указывает левый, содержит все квалификаторы типа, на который указывает правый.
Возможно, вы захотите скомпилировать с -pedantic-errors
, чтобы получить ошибки вместопредупреждений о нарушениях языка C.
Что касается четко определенного поведения, то есть до тех пор, пока вы отменяете указатель, используя правильный тип фактических данных, это четко определенное поведение, итип самого указателя не имеет большого значения.
Я даже не понимаю, почему вам нужно преобразовать в void*
, поскольку формат вашего обратного вызова таков:
int (*comp)(const void *, const void *)
Так что единственная проблема - это тип возвращаемого значениявнешняя функция, которую можно упростить до чего-то вроде этого:
void* vector_lsearch (const void* key, const void* base, int (*comp)(const void*, const void*))
{
const struct vector* vector = CONST_VECTOR(base);
void* result = NULL;
unsigned char* data = (unsigned char*)base;
for (size_t i=0; i < vector->size; i++)
{
if (comp(&data[i*vector->szof], key) == 0)
{
result = data;
break;
}
}
return result;
}
CONST_VECTOR
хотя и подозрительно, пахнет, будто вы прячете гипс за макросом или чем-то еще?