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

Может ли void * использоваться для хранения указателей функций?

void * определяется таким образом, что он может указывать на любую вещь. Так может ли он использоваться для указания функции (int send())?

int send();
void* p = send;

Возможно ли это? Когда я использую это, это не показывает мне ошибки почему? Если нет, есть ли способ сохранить все указатели в одной переменной?

4b9b3361

Ответ 1

Нет, не может.

В соответствии со стандартом C (6.3.2.3 указатели)

1 Указатель на void может быть преобразован в указатель или из указателя на любой тип объекта. Указатель на любой тип объекта может быть преобразован в указатель на void и обратно; результат сравнивается равным исходный указатель.

Что касается указателей функций, то

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

В стандарте С++ существует более подробное определение указателей (3.9.2. Составные типы)

3 Тип указатель на void или указатель на тип объекта называемый указателем типа объекта.... Тип указателя, который может обозначить функцию называется указателем функции.

и

4 Можно использовать указатель на cv-квалификацию (3.9.3) или cv-unqualified voidуказывать на o bjects неизвестного типа. Такой указатель должен иметь возможность удерживайте любой указатель объекта. Объект типа cv void * должен иметь те же требования к представлению и выравниванию, что и cv char *.

Ответ 2

Может быть. До С++ 11 они не могли; но С++ 11 добавляет:

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

Это, похоже, пока не превратило его в C.

Причина, по которой вы не можете конвертировать между ними, конечно, состоит в том, что они могут не иметь того же размера или формата. Posix требует, чтобы они имеют одинаковый размер и формат, и я ожидал бы, что все компиляторы Posix будут поддерживать конверсию; большинство из них делалось раньше, хотя это и делало их не-совместимый.

EDIT:

Немного больше информации. Перечитав стандарт C, я думаю преобразования между указателями объектов и указателями функций undefined поведение: стандарт C, похоже, не требует диагностики в этом но он определенно не определяет никакого поведения для него. В виде undefined, реализация (или Posix) может ее определить. Или просто сделайте все, что захотите, без документирования.

С другой стороны, С++, pre С++ 11, требовал диагностики (хотя ряд компиляторов не дал). В С++ 11, согласно абзацу приведенное выше, реализация определяется, является ли реализация поддерживает это или нет, и если реализация поддерживает это, они необходимых для документирования его поведения. Таким образом, во всех случаях реализация требуется для документирования того, что он делает, и если он не поддерживает его, он требуется для диагностики, если код пытается выполнить преобразование.