Ответ 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');
Я могу 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.
Что мне не хватает, чтобы удалить предупреждение при печати адреса функции?
Это, по сути, единственный переносимый способ печати указателя функции.
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');
Вся эта идея действительно не переносима, поскольку некоторые системы используют указатели разного размера для кода и данных.
Что вам действительно нужно, это знание конкретной платформы о том, насколько большой указатель функции, и приведение к целостному типу такого размера. К сожалению, я не думаю, что кто-то стандартизовал intfuncptr_t
analagous для intptr_t
, который может содержать любой указатель данных.
Поскольку R. отмечает в своем ответе, вы всегда можете рассматривать указатель как массив (возможно signed
или unsigned
) char
, этот вам не нужен какой-либо целостный тип правильного размера.
Именно там в предупреждении: ISO C запрещает преобразование указателя функции на тип указателя объекта, который включает void*
. См. Также этот вопрос.
Вы просто не можете печатать адрес функции переносимым способом, поэтому вы не можете избавиться от предупреждения.
Вы можете напечатать указатель на функцию с помощью предложения @R..
При преобразовании указателя функции в указатель void технически опасно, преобразование указателей функций в указатели void используется в стандарте POSIX, поэтому почти наверняка будет работать на большинстве компиляторов.
Посмотрите dlsym()
.