Встроенные функции

Можно ли получить адрес встроенной функции, и почему?


Ответы (1 шт):

Автор решения: Serge3leo

Для C23/C++11, в простейшем случае, это делается просто:

    auto s1 = sin;

Однако, "встроенные функции", которые определены в стандартах, могут иметь достаточно сложный интерфейс. Какой именно, подскажет выдача компилятора. Непростые случаи бывают, скажем, такие:

  1. "Встроенная функция", вовсе не функция, а оператор, например, sizeof(). Адрес оператора получить нельзя;

  2. "Встроенная функция", вовсе не функция, а макрос, например, тот же sin(), но если включить #include <tgmath.h>. Адрес макроса получить нельзя;

  3. "Встроенная функция" - перегруженная функция, например, std::sin(). При использовании выбор происходит на основе аргументов, но при получении адреса необходимо указать адрес какой именно перегрузки Вы желаете:

    // auto s2 = std::sin;
    double (*s2d)(double) = std::sin;
    float (*s2f)(float) = std::sin;
  1. "Встроенная функция" - шаблон функции, например, std::size() (он хитрым образом перегружен, но clang/gcc/intel это совсем не мешает). Часто, при использовании выбор происходит на основе аргументов, но при получении адреса необходимо явно указать параметры шаблона:
    auto f1 = std::size<int, 1>;
    auto f2 = std::size<int, 2>;

    static_assert(typeid(f1) != typeid(f2));
    std::println("f1: {}\nf2: {}",
                 typeid(f1).name(), typeid(f2).name());

    #if !defined(_MSC_VER)  // TODO неоднозначность специализации
        static_assert(typeid(std::size<int, 1>)
                      != typeid(std::size<int, 2>));
        std::println("typeid(std::size<int, 1>): {}\n"
                     "typeid(std::size<int, 2>): {}",
                     typeid(std::size<int, 1>).name(),
                     typeid(std::size<int, 2>).name());
    #endif

P.S.

В части перегруженных шаблонов, возможно, ответ неполный. По крайней мере, поведение последнего MSVC 19.50 (Visual Studio 2026), или более ранних, мне непонятно. Надо будет разбираться, если в комментариях не поправят.

P.P.S.

С точки зрения стандартов варианты функции sin(), как и другие упомянутые в стандарте - встроенные (аналог fortan intrinsic). Никто не знает, что будет, если её попытаться переопределить и, формально, это запрещено.

Что касается конкретной реализации, стандарт один (или два C/C++), а компиляторов, что собак нерезаных. Наверняка были/есть, у которых она в других модулях трансляции. Так же наверняка были/есть, у которых она комбинируется в одну или в две команды процессора.

Но с точки зрения языка(ов), это функция, её адрес можно получить, как описано выше.

→ Ссылка