Почему функция, ожидающая ссылку, работает с указателем? - PullRequest
4 голосов
/ 24 апреля 2020

Я пишу программу на C ++, которая использует библиотеку C. Эта библиотека берет указатели на функции для обратных вызовов, и я хочу, чтобы она вызывала методы экземпляра. К счастью, библиотека принимает дополнительный параметр данных, который является просто «void *» и передается без изменений в обратный вызов. Итак, я создал обобщенную c функцию-оболочку обратного вызова.

void callbackWrapper(std::function<void ()> &func) {
    func();
}

Теперь, когда мне нужно зарегистрировать обратный вызов в библиотеке, я передаю указатель на функцию callbackWrapper в качестве вызываемой функции, и указатель на функцию std :: как дополнительный параметр данных. Когда происходит обратный вызов, он вызывает мою оболочку, которая затем вызывает фактический метод / лямбда / то, что я действительно хотел вызвать.

Но в приведенном выше коде есть ошибка. Я использовал «&» вместо «*», что означает, что функция ожидает ссылку на std :: function, а не указатель. Функция должна была определена так:

void callbackWrapper(std::function<void ()> *func) {
    (*func)();
}

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

  1. Стандарт C ++ позволяет автоматизировать c продвижение указателей на ссылки в этом случае.
  2. Мой компилятор (g cc 9.3.1) заметил несоответствие и тихо исправил его для меня.
  3. Адрес указателя просто оказался в нужном месте в кадре стека, что вызов может быть успешным.

Любые мои теории верны? Если нет, что случилось?

1 Ответ

1 голос
/ 24 апреля 2020

Скорее всего, для вашего примера верен случай 3.

Очень разумно передавать ссылки, как если бы они были указателями, большинство ABI, вероятно, делают это.

Например, Itanium C ++ ABI говорит (это ABI, который используется, например, в Linux / x64):

Справочные параметры обрабатываются путем передачи указателя на объект, связанный с ссылка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...