Встроенные функции
Можно ли получить адрес встроенной функции, и почему?
Ответы (1 шт):
Для C23/C++11, в простейшем случае, это делается просто:
auto s1 = sin;
Однако, "встроенные функции", которые определены в стандартах, могут иметь достаточно сложный интерфейс. Какой именно, подскажет выдача компилятора. Непростые случаи бывают, скажем, такие:
"Встроенная функция", вовсе не функция, а оператор, например,
sizeof(). Адрес оператора получить нельзя;"Встроенная функция", вовсе не функция, а макрос, например, тот же
sin(), но если включить#include <tgmath.h>. Адрес макроса получить нельзя;"Встроенная функция" - перегруженная функция, например,
std::sin(). При использовании выбор происходит на основе аргументов, но при получении адреса необходимо указать адрес какой именно перегрузки Вы желаете:
// auto s2 = std::sin;
double (*s2d)(double) = std::sin;
float (*s2f)(float) = std::sin;
- "Встроенная функция" - шаблон функции, например,
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++), а компиляторов, что собак нерезаных. Наверняка были/есть, у которых она в других модулях трансляции. Так же наверняка были/есть, у которых она комбинируется в одну или в две команды процессора.
Но с точки зрения языка(ов), это функция, её адрес можно получить, как описано выше.