|
|||||||
Как получить адрес функции в языке C++
Время создания: 18.02.2022 11:47
Текстовые метки: язык, Си++, C++, указатель, функция, адрес
Раздел: Компьютер - Программирование - Язык C++ (Си++)
Запись: xintrea/mytetra_syncro/master/base/16451740798lx4rucxsx/text.html на raw.github.com
|
|||||||
|
|||||||
Получить адрес функции в виде числа в языке Си++ можно через приведение указателя на функцию к нужному числовому типу. Делается это через стандартную шаблонную функцию reinterpret_cast<...>(...). Данная функция не приводит типы, а позволяет рассматривать область памяти, которая выделена под переменную, в виде заданного в угловых стрелках типа. То есть, выглядит преобразование следующим образом: #include <iostream> #include <stdio.h> // Код функции func() находится в ячейке, например, памяти 64C18F7249B0 int func() { return 7; }
int main() { // C-стиль получения адреса в виде числа, // такую запись можно использовать и в C++ unsigned long a = reinterpret_cast<unsigned long>( func ); // C++ - стиль вывода в консоль напрямую std::cout << func; // C++ - стиль вывода в консоль через приведение к типу void* std::cout << reinterpret_cast<void*>(func);
return 0; } В консоль будет выведено: a = 64C18F7249B0 1 0x64C18F7249B0 Получение адреса работает одинаково для Си и Си++. А вот вывод значения указателя на функцию в стандартный поток для Си++ имеет особенности. Если просто попыпаться напечатать значение указателя на функцию через стандартный консольный поток std::cout, то будет выведено 1. Почему так? Дело в том, что переменная func имеет тип указателя на функцию, а не просто числовой тип. Вывод зависит от функции-оператора <<, которая имеет кучу прототипов для различных типов:
Перед выводом язык видит, что передан указатель (неважно, на переменную или на функцию), и преобразует его в bool-значение. Почему так происходит? Перегрузки оператора << для вывода адреса функций нет. Нет потому, что тип указателя на функцию зависит от вида самой функции, а он для разных функций неопределен - ибо он может быть совершенно разный. Зато есть перегрузка для вывода bool. А у указателя любого типа есть преобразование в тип bool, причем оно стоит на первом месте в приоритете по сравнению со всеми другими преобразованиями типов. Соответственно указатель на функцию неявно преобразуется в bool. Вывести значение адреса можно явно преобразовав указатель на функцию к указателю на void* (перегрузка оператора << для которого как раз печатает значение адреса): 29.7.5.1 Class template basic_ostream [ostream] namespace std { template<class charT, class traits = char_traits<charT>> class basic_ostream : virtual public basic_ios<charT, traits> {
public: ... // 29.7.5.2, formatted output basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& (*pf)(basic_ostream<charT, traits>&)); basic_ostream<charT, traits>& operator<<(basic_ios<charT, traits>& (*pf)(basic_ios<charT, traits>&)); basic_ostream<charT, traits>& operator<<(ios_base& (*pf)(ios_base&)); basic_ostream<charT, traits>& operator<<(bool n); basic_ostream<charT, traits>& operator<<(short n); basic_ostream<charT, traits>& operator<<(unsigned short n); basic_ostream<charT, traits>& operator<<(int n); basic_ostream<charT, traits>& operator<<(unsigned int n); basic_ostream<charT, traits>& operator<<(long n); basic_ostream<charT, traits>& operator<<(unsigned long n); basic_ostream<charT, traits>& operator<<(long long n); basic_ostream<charT, traits>& operator<<(unsigned long long n); basic_ostream<charT, traits>& operator<<(float f); basic_ostream<charT, traits>& operator<<(double f); basic_ostream<charT, traits>& operator<<(long double f); То же самое происходит и при выводе в стандартный поток. Указатель преобразуется в bool и прогоняется через bool-вариант функции-оператора <<, и в стандартный поток попадает значение true, которое отображается как 1. В случае же приведения к типу void*, используется вариант с параметром const void* value, который выводит шестнадцатеричное число. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|