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

Ограничения POSIX для типов указателей в C

Фон

стандарт POSIX добавляет множество функций библиотеки и других идентификаторов к языку C. В описании функции dlsym() она говорит (с моим акцентом):

СИНТАКСИС

#include <dlfcn.h>

void *dlsym(void *restrict handle, const char *restrict name);

ОПИСАНИЕ

Функция dlsym() должна получить адрес символа ( идентификатор функции или идентификатор объекта данных)...

Стандарт C не гарантирует, что указатель функции может быть преобразован в void *, или даже если размер указателей одинаковый. Это эффективно добавляет дополнительное ограничение на систему типа C.

Вопрос

Мой вопрос:

  • Существует ли нормативная ссылка для этого ограничения системы типа C, или она выводима только из описания некоторых библиотечных функций?
  • Является ли POSIX даже реализуемым в системе, где sizeof (function pointer) > sizeof (void *)?

Ссылки

4b9b3361

Ответ 1

Ссылка dlsym() говорит, что преобразование не определено стандартом C, но что соответствующая реализация должна заставить эту работу работать правильно. Таким образом, в системах, где это не может быть выполнено, не будет соответствующей реализации и, вероятно, будет задокументировано это:

Обратите внимание, что преобразование из указателя void * в указатель на функцию, как в:

fptr = (int (*)(int))dlsym(handle, "my_function");

не определяется стандартом ISO C. Этот стандарт требует, чтобы это преобразование корректно работало на соответствующих реализациях.

есть старая статья, которая говорит об этом с точки зрения C++ и ссылается на более старую версию ссылки dlsym() и имеет более подробное объяснение:

Стандарт ISO C не требует, чтобы указатели на функции могли приводиться назад и вперед к указателям на данные. Действительно, стандарт ISO C не требует, чтобы объект типа void * мог содержать указатель на функцию. Реализации, поддерживающие расширение XSI, однако, требуют, чтобы объект типа void * мог содержать указатель на функцию. Однако результат преобразования указателя на функцию в указатель на другой тип данных (кроме void *) все еще не определен. Обратите внимание, что компиляторы, соответствующие стандарту ISO C, должны генерировать предупреждение, если выполняется попытка преобразования из указателя void * в указатель функции, как в:

fptr = (int (*)(int))dlsym(handle, "my_function");

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