Почему компиляторы ведут себя по-разному, когда static_cast (ing) выполняет функцию void *? - PullRequest
9 голосов
/ 24 марта 2019

Следующий код компилируется без ошибок в VSC ++ 2017 и не компилируется в gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’ void* p = static_cast<void*>(func))

#include <iostream>

int func(int x) { return 2 * x; }

int main() {

    void* p = static_cast<void*>(func);
    return 0;
}

1 Ответ

9 голосов
/ 24 марта 2019

Функции неявно преобразуются только в указатели на функции. указатель на функцию не является указателем в строгом смысле слова в языке, который относится только к указателям на объекты.

Функциональные указатели не могут быть преобразованы в void* с помощью static_cast. Показанная программа некорректна. Если компилятор не предупреждает, он не соответствует стандарту. Невозможность скомпилировать неправильно сформированную программу не нарушает стандарт.


В системах, где void* гарантированно может указывать на функцию (например, POSIX), вместо нее можно использовать reinterpret_cast:

void* p = reinterpret_cast<void*>(func);

Но это не переносимо на системы, в которых нет гарантии. (Я не знаю ни одной системы, которая бы имела компилятор C ++ и не имеет такой гарантии, но это не значит, что такой системы не существует).

Стандартная цитата:

* * Тысяча двадцать-одина [expr.reinterpret.cast]

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

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

...