Эквивалент uintptr_t / intptr_t для указателей на функции?

Afaik uintptr_t и intptr_t можно использовать для хранения любого указателя на void. Следовательно, эти типы можно использовать для хранения указателей на данные.

В C99 или более поздних версиях существуют ли похожие целочисленные типы со знаком и без знака, способные содержать указатели на функции?


person jotik    schedule 04.04.2016    source источник
comment
Единого указателя на тип функции не существует (каждый тип зависит от прототипа функции).   -  person barak manos    schedule 04.04.2016
comment
Вы даже не можете преобразовать указатель на функцию в void *. Также C и C ++ - это разные языки. Пожалуйста, ограничьте свой вопрос одним из них.   -  person too honest for this site    schedule 04.04.2016
comment
@barakmanos Истинно, но каждый тип указателя на функцию может хранить любой другой тип указателя на функцию после преобразования, поэтому, если у вас есть целочисленный тип, достаточно большой для одного типа указателя на функцию, у вас должен быть целочисленный тип large хватит на всех.   -  person    schedule 04.04.2016
comment
@Olaf Вы можете преобразовать его в достаточно большой целочисленный тип. Просто нет гарантии, что какой-либо целочисленный тип будет достаточно большим.   -  person    schedule 04.04.2016
comment
@hvd: Да, нашел сам. Я действительно был уверен, что там тоже используется термин «указатель на объект». Извините за путаницу. Я удалил свои комментарии.   -  person too honest for this site    schedule 04.04.2016


Ответы (1)


Нет, таких нет.

Указатели функций могут быть надежно преобразованы только в другие типы указателей функций (и затем разыменование только при указании на правильный тип функции).

Преобразование указателей на функции в целые числа в C описывается в 6.3.2.3/6:

Любой тип указателя может быть преобразован в целочисленный тип. За исключением случаев, указанных ранее, результат определяется реализацией. Если результат не может быть представлен в виде целого числа, поведение не определено. Результат не обязательно должен находиться в диапазоне значений какого-либо целочисленного типа.

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

В C ++ текст находится в точках 4 и 6 [expr.reinterpret.cast]. Поведение аналогично, но явно гарантирует, что если существует целое число достаточного размера, то преобразование указателя функции в целое число и обратно возвращает исходный указатель на функцию.

person M.M    schedule 04.04.2016
comment
Просто добавлю, что реализация должна указывать поведение , определяемое реализацией. Таким образом, нужно иметь возможность узнать, действительно ли такое преобразование для конкретной реализации и как. Это может быть сделано с помощью ABI, не обязательно в компиляторе. Подобное преобразование могло бы быть возможным между void * и указателем функции (см. J.5.7). - person too honest for this site; 04.04.2016
comment
Просто чтобы проинформировать других читателей: J.5 в стандарте C - это раздел об общих расширениях языка C в информативном (не нормативном) приложении J о проблемах переносимости. - person jotik; 04.04.2016
comment
Вы можете сделать преобразование надежным: _Static_assert(sizeof(uintptr_t) >= sizeof(func_pointer_t), "bleh");. Тогда такие преобразования будут терпеть неудачу только в малоизвестных системах, где указатели чем-то отличаются от адресов (IMO такие системы в любом случае заслуживают сбоя). - person Lundin; 06.04.2016
comment
@Lundin: Тот факт, что указатели на функции и другие указатели имеют разный размер, не означает, что указатели отличаются от адресов. Не каждая машина принадлежит фон Нейману (на самом деле, поскольку встроенных процессоров намного больше, чем настольных и, поскольку x86 технически не является фон Нейманом для загрузки [это гибрид], я бы сказал, что большинство системы не фон Неймана). Во встроенных функциях указатели часто больше, чем другие (при этом они часто - но НЕ всегда - дополняются одним и тем же типом в любом случае в C). - person Tim Čas; 12.06.2016
comment
@ TimČas стандарт даже специально говорит, что адреса являются указателями. (С11 6.5.3.2/3). Я предполагаю, что указатели не являются адресной толпой, на самом деле это означает, что указатели не являются целыми числами, что в некотором смысле иронично. - person M.M; 13.06.2016
comment
@ M.M: Все, что я говорю, это то, что то, что sizeof(void (*)(void)) и sizeof(void*) могут быть разными, не означает, что они не являются адресами. И это также не означает, что вы можете просто преобразовать одно в другое (на практике вы можете в x86 [POSIX, например, явно заявляет, что приведение четко определено], но, как я уже сказал, не в Гарвардской архитектуре систем, поскольку указатели функций обычно указывают на программную память, а обычные - на ОЗУ). - person Tim Čas; 15.06.2016
comment
@ TimČas да, я согласен с тобой - person M.M; 15.06.2016