Можно ли передать указатель на функцию в качестве аргумента const?
Я получаю следующую ошибку gcc:
warning: type defaults to 'int' in declaration of 'f' [-Wimplicit-int] void execute(void (const *f)(void));
... при компиляции этого кода:
#include <stdio.h>
void print(void);
void execute(void (const *f)(void));
int main(void)
{
execute(print); // sends address of print
return 0;
}
void print(void)
{
printf("const!");
}
void execute(void (const *f)(void)) // receive address of print
{
f();
}
Это не дубликат Что означает указатель на постоянную функцию?, который адресует указатели на константные функции в отличие от Аргумент функции const.





Ключевое слово const следует поместить между символом указателя (*) и именем аргумента (здесь f):
void execute(void (* const f)(void))
{
f();
}
Теперь, если вы попытаетесь изменить значение f:
void execute(void (* const f)(void))
{
f = print;
f();
}
... ваш компилятор должен вывести ошибку, аналогичную этой, как и ожидалось:
Error: cannot assign to variable 'f' with const-qualified type
Желаемый синтаксис:
void execute(void (* const f)(void));
Это говорит о том, что f - это указатель const на функцию, которая не принимает аргументов ((void) - это специальный синтаксис без аргументов) и ничего не возвращает (void). const на правой стороне * говорит, что указатель - это const. const на левой стороне указывает указатель указывает на что-то, который является const.
Тот факт, что это указатель const, означает, что вы не будете изменять f (назначать новое значение) в функции, и компилятор должен выдать вам ошибку, если вы это сделаете (если изменение не скрыто от него, что может быть слепки). Он ничего не говорит о самой функции - указанная функция не является const ни в каком смысле, потому что параметр - это const.
Когда вы написали:
void execute(void (const * f)(void));
const на левой стороне * означает, что указатель указывал на что-то, что было const, а не на то, что сам указатель был const. Поскольку он говорил, что указатель указывает на что-то там, а вы не указали конкретный тип, компилятор предупредил вас, что тип отсутствует (и по умолчанию установлен int).