Правильный синтаксис для хранения указателя на функцию - PullRequest
17 голосов
/ 25 мая 2020

Удивительно, но следующий код хорошо компилируется как в g cc, так и в clang независимо от того, какой символ перед именем функции используется: *, & или ничего. Допускает ли стандарт какой-либо из них? Какой способ хранения указателей на функции является предпочтительным?

#include <stdio.h>

typedef int foo(int a);

template <typename X>
int g(int y) {
    return y * sizeof(X);
}

int main() {

    foo* xxx;

    // 1. what is correct according to standard?
    // 2. why they all work?
    xxx = *g<float>;
    xxx = &g<float>;
    xxx = g<float>;

    printf("ok %d\n", xxx(5));
}

1 Ответ

15 голосов
/ 25 мая 2020

Все должно работать нормально и иметь тот же эффект. Какой из них предпочтительнее, это проблема стиля, IMO первый в вашем коде сбивает с толку, два других - довольно распространенное использование.

Для удобства я объясню в обратном порядке вашего кода,

  1. Для xxx = g<float>;, неявное преобразование функции в указатель выполняется из g<float>, преобразованный указатель присваивается xxx.

  2. Для xxx = &g<float>;, operator& используется явно для получения адреса функции, возвращаемый указатель присваивается xxx.

  3. Для xxx = *g<float>; выполняется неявное преобразование функции в указатель из g<float>, затем указатель разыменовывается с помощью operator*, который возвращает ссылку на функцию, на которой функция-в -pointer неявное преобразование выполняется (снова), преобразованный указатель наконец присваивается xxx.

...