Какво представлява стойността на указателя на указател на функция?

Опитвате се да разберете какво всъщност представлява указателят към функцията? Това ли е адресът в кодовия сегмент, където се намира функцията?

Например: тази част от кода:

#include <stdio.h>

void foo(void)
{
}

int main(void)
{
    int a = 10;
    printf("a's address: %p\n", &a);
    printf("foo's address: %p\n", foo);
    return 0;
}

... отпечатва това:

[sh/prog-exercises/adam]:./a.out 
a's address: 0xbfffb414 
foo's address: 0x8048430

Предполагам, че съм малко объркан с това как точно стекът/купчината на процес се свързва с ELF сегмент от данни/код-сегмент. Всякакви полезни насоки биха били наистина добре дошли. Също така, първият ми въпрос, така че, моля, бъдете нежни, наистина се опитвам да се науча. Благодаря!


person helpmelearn    schedule 14.10.2010    source източник


Отговори (3)


Това е адресът на входната точка на функцията - началото на нейния код. Променливата a се намира в стека, така че не е изненадващо, че адресът й се различава значително - на стека и кода са присвоени различни кодови области, които могат да бъдат доста далеч един от друг.

person sharptooth    schedule 14.10.2010
comment
Точно така, изходът тук представлява местоположението, където тази конкретна функция е била заредена като част от кодовия сегмент? Има ли начин C програма да отпечата сегмента с данни, началните/крайните адреси на кодовия сегмент? - person helpmelearn; 14.10.2010
comment
@helpmelearn: Да, това е адресът, където се намира началото на функцията. Не знам за решение за намиране на адресите на сегментите и предполагам, че ще зависи от изпълнението. Може би има помощна програма, която може да направи това за всеки процес. - person sharptooth; 14.10.2010

Това изображение от книгата UNIX: Системно програмиране трябва да изясни нещата .

В долната част на диаграмата имате програмния си текст (малки адреси). Както може да се провери от вашата програма. Това е мястото, където ще се намира foo().

алт текст

person Srikar Appalaraju    schedule 14.10.2010

Едно нещо, което трябва да имате предвид е, че вашият код не е напълно съвместим със стандартите. Ако използвате gcc -Wall -Wextra -pedantic -ansi, ще получите оплакване за реда, където отпечатвате указателя на функцията. Това е така, защото стандартът не гарантира, че функционалните указатели могат да бъдат преобразувани в void указатели. C е проектиран да работи на много различни архитектури и ако архитектурата е архитектура на Харвард (отделна памет за инструкции и данни), може да има основателни причини тези указатели да бъдат с различни размери.

Предполагам, че на практика е малко вероятно да има значение, но е добър факт, който трябва да знаете. Особено когато се опитвате да научите интимните подробности на C.

person kasterma    schedule 27.10.2010