Указатель функции содержит адрес функции - что бы это ни значило для данной системы. Вы можете использовать его для косвенного вызова функции, вы можете назначать и сравнивать значения указателя на функцию. Вы также можете преобразовать указатель функции в другой тип указателя на функцию и т. Д.
Самый простой способ для компилятора реализовать указатель на функцию - это адрес памяти функции, и большинство компиляторов делают это таким образом, но в стандарте языка это не указано. Некоторые системы (я думаю, что IBM AS / 400 является примером) хранят дополнительную информацию в функциональных указателях. Компилятор может реализовывать указатели на функции в виде целочисленных индексов в таблице дескрипторов, если требуемая семантика реализована правильно.
Невозможно разыменовать указатель на функцию. Для вызова функции в качестве префиксного выражения требуется указатель, а не имя функции; если вы используете имя функции, это имя неявно преобразуется в указатель (что касается языка; сгенерированный машинный код может отличаться). Таким образом, у программы нет портативного способа определить, содержат ли указатели функций адреса памяти или нет.
Не переносимо, учитывая функцию func
, вы можете сделать что-то вроде:
printf("Address of func is %p\n", (void*)func);
и вы , вероятно, увидите нечто, похожее на читаемое человеком представление адреса памяти. Но, строго говоря, поведение преобразования указателя функции в void*
не определяется языком и может не работать в некоторых системах.
Вы могли бы даже иметь возможность преобразовать указатель функции в unsigned char*
и проверить машинный код функции, но выходит далеко за рамки всего, что определено стандартом C.
Лучше всего обращаться с указателями на функции как с непрозрачными значениями, которые каким-либо неуказанным образом ссылаются на конкретные функции.