A void *
можно безопасно преобразовать в / из любого другого типа, но это не то преобразование, которое вы пытаетесь сделать.Вы пытаетесь конвертировать int (*)(A *, A *)
в int (*)(void *, void*)
.Это две совершенно разные вещи.
Автоматическое преобразование void *
не применяется к аргументам в указателе функции.Для совместимости двух указателей на функции число и тип аргументов должны быть совместимы, а также тип возвращаемого значения.
Одна из причин этого заключается в том, что void *
не обязательно должно иметь такое же представление, какдругие типы указателей.Это хорошо при простом преобразовании в void *
и обратно, что явно разрешено стандартом, однако это может быть проблемой при вызове функции.
Предположим, что void *
представлен 8 байтами, а указатель структуры представлен 4 байтами.В вашем примере два 8-байтовых значения будут помещены в стек, но два 4-байтовых значения будут считаны из стека в качестве параметров функции.Это приведет к недопустимым значениям указателя, которые впоследствии будут разыменованы.