Указатель на функцию как константный аргумент

Можно ли передать указатель на функцию в качестве аргумента 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.

stackoverflow.com/questions/10145693/…
zzxyz 24.03.2018 00:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
1
872
2

Ответы 2

Ключевое слово 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).

Другие вопросы по теме