Подтвердить что ты не робот

Как распечатать адрес функции?

Я могу gcc скомпилировать следующий пример, используя -Wall -pedantic:

#include <stdio.h>

int main(void)
{
  printf("main: %p\n", main); /* line 5 */
  printf("main: %p\n", (void*) main); /* line 6 */

  return 0;
}

Я получаю:

main.c:5: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int (*)()’
main.c:6: warning: ISO C forbids conversion of function pointer to object pointer type

Строка 5 изменила код, как в строке 6.

Что мне не хватает, чтобы удалить предупреждение при печати адреса функции?

4b9b3361

Ответ 1

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

size_t i;
int (*ptr_to_main)() = main;
for (i=0; i<sizeof ptr_to_main; i++)
    printf("%.2x", ((unsigned char *)&ptr_to_main)[i]);
putchar('\n');

Ответ 2

Вся эта идея действительно не переносима, поскольку некоторые системы используют указатели разного размера для кода и данных.

Что вам действительно нужно, это знание конкретной платформы о том, насколько большой указатель функции, и приведение к целостному типу такого размера. К сожалению, я не думаю, что кто-то стандартизовал intfuncptr_t analagous для intptr_t, который может содержать любой указатель данных.


Поскольку R. отмечает в своем ответе, вы всегда можете рассматривать указатель как массив (возможно signed или unsigned) char, этот вам не нужен какой-либо целостный тип правильного размера.

Ответ 3

Именно там в предупреждении: ISO C запрещает преобразование указателя функции на тип указателя объекта, который включает void*. См. Также этот вопрос.

Вы просто не можете печатать адрес функции переносимым способом, поэтому вы не можете избавиться от предупреждения.

Вы можете напечатать указатель на функцию с помощью предложения @R..

Ответ 4

При преобразовании указателя функции в указатель void технически опасно, преобразование указателей функций в указатели void используется в стандарте POSIX, поэтому почти наверняка будет работать на большинстве компиляторов.

Посмотрите dlsym().