Похоже, вы нашли что-то, что авторы компиляторов и разработчики стандартов не учли. Из проекта C99 N1256, § 6.7.5.3, пункт 15,
соответствующие параметры должны иметь совместимые типы.
Обратите внимание, что const int *
не совместимо с int *
. Однако int *
может быть преобразовано в const int *
. Из §6.3.2.3, пункт 2,
Для любого квалификатора q указатель на неквалифицированный тип q может быть преобразован в указатель на q квалифицированную версию тип
Более сложные правила для вывода, когда допустимо заменять типы, полученные из квалифицированных или неквалифицированных версий одного и того же типа, просто отсутствуют в стандарте. Следовательно, ваш код технически нарушает стандарт.
Мой вывод: Мне кажется, что эта ошибка должна рассматриваться компилятором как "педантичная": ваш код технически не соответствует стандарту, но смысл однозначно и код абсолютно безопасен. Не стесняйтесь написать запрос функции вашему поставщику компилятора. Существует множество несоответствующих практик, которые не генерируют предупреждения без -pedantic
.
В качестве заключительного замечания я скомпилировал с Clang, и компилятор сообщил мне, что предупреждение было педантичным. Однако я не просил педантичных предупреждений ... так что, похоже, нет способа его отключить.
warning: incompatible pointer types passing 'void (int const *)', expected 'void (*)(int *)'
<b>[-pedantic]</b>
Обходной путь: Использовать явное приведение.
void g(const int *);
f((void (*)(int *)) g);