Преобразование указателя на функцию в другой указатель на функцию определяется стандартом c, но использование результирующего указателя для вызова функции с несовместимым типом недопустимо для C 6.3.2.3 8:
Указатель на функцию одного типа может быть преобразован в указатель на функцию другого типа и обратно; результат должен сравниваться равным исходному указателю. Если преобразованный указатель используется для вызова функции, тип которой не совместим с указанным типом, поведение не определено.
Объявление void scriveTitolo2() { … }
определяет функцию, у которой нет списка типов параметров. (он использует старый стиль C списка идентификаторов, при этом этот список пуст), и это не требует аргументов. Указатель Callback
указывает на функцию, которая имеет список типов параметров и принимает аргумент const char *
. Они несовместимы в соответствии с C 2018 6.7.6.3 15:
Для совместимости двух типов функций… Если один тип имеет список типов параметров, а другой тип определяется определением функции, которое содержит (возможно, пустой) список идентификаторов, оба должны совпадать по количеству параметров,…
Поскольку они не совпадают по количеству параметров, они несовместимы.
выше говорит только о проблеме преобразования из void (*)()
в void (*){const char *)
и использования результата для вызова функции. Существует отдельная проблема в том, что указатель функции передается в inserisce_cb
, который принимает аргумент типа void *
, который является указателем на тип объекта. Стандарт C не определяет поведение преобразования указателя на тип функции в указатель на тип объекта. Чтобы исправить это, необходимо объявить inserisce_cb
для получения указателя на тип функции, такой как void inserisce_cb(Callback c)
.
Если можно изменить scriveTitolo2
, то проблему совместимости можно решить, изменив ее на возьмите параметр const char *
, который не используется, изменив его определение на void scriveTitolo2(const char *)
.
(Обратите внимание, что лучше объявить scriveTitolo2
с современным стилем C, как void scriveTitolo2(void) { … }
, чем без void
. Это не связано с вопросом, так как это не сделает типы функций совместимыми, но этот формат объявления предоставляет компилятору больше информации при многих обстоятельствах.)