TransWikia.com

Почему адрес функции, полученный через указатель, всегда равен 1?

Stack Overflow на русском Asked by S.H. on August 30, 2021

Я получил немного странный результат.

Если я напишу какое то простое выражение с указателем, например,

    int a = 10;
    cout << &a << endl;

то в консоль будет выведено что то типа 0x66fe1c, что похоже на адрес в памяти.

Но если я проделаю то же с указателем на функцию, я всегда получаю "1".

Пример:

    #include <iostream>
    using namespace std;

    void add(int a, int b){
        cout << a+b << endl;
    };

    void subtract(int a, int b){
        cout << a-b << endl;
    };

    void multiply(int a, int b){
        cout << a*b << endl;
    };

    int main(){

        void (*operations[3])(int, int) = {add, subtract, multiply};
        
        int length = sizeof(operations)/sizeof(operations[0]);

        for(int i=0; i<length;++i){
            cout << operations[i] << endl;
        }

        return 1;
    }

программа выведет

    1
    1
    1

То есть, массив указателей на три разные функции содержит три одинаковых, и не похожих на адреса в памяти, значения.

В чем тут дело? что я делаю не так, и как получить "адрес функции в памяти"?

Спасибо заранее!

3 Answers

Зависит от компилятора. VC++, например, честно выводит адреса. GCC преобразует их в bool, как я понимаю (тут пусть гуру в стандарте скажут, верно это или нет).

Хотите оставить адреса - выполните приведение типов, в простейшем варианте как

cout << (void*)operations[i] << endl;

Полный код см. тут.

Correct answer by Harry on August 30, 2021

Как сказано в документации https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt:

There are no overload for pointers to non-static member, pointers to volatile, or function pointers (other than the ones with signatures accepted by the (10-12) overloads). Attempting to output such objects invokes implicit conversion to bool, and, for any non-null pointer value, the value 1 is printed (unless boolalpha was set, in which case true is printed).

То есть для указателей на функции нет специальной перегрузки и при попытке их вывода будет неявное преобразование к типу bool.

Answered by dIm0n on August 30, 2021

Большое спасибо!

Про приведение к bool - я бы сам точно не догадался.

По меньшей мере, gcc может добраться до адресов так:

    #include <iostream>

    int boo(){
        return 7;
    };

    int doo(){
        return 8;
    }

    int main(){
        
        cout << "boo addr = "<< reinterpret_cast<void*>(boo) << endl;
        cout << "doo addr = "<< reinterpret_cast<void*>(doo) << endl;

    }

Answered by S.H. on August 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP