Что означает примечание ниже в [expr.reinterpret.cast]/6?

http://eel.is/c++draft/expr.reinterpret.cast#6:

Указатель на функцию может быть явно преобразован в указатель на функцию другого типа. [ Примечание: эффект вызова функции через указатель на тип функции ([dcl.fct]), который отличается от типа, используемого в определении функции, не определен. - примечание конца ] За исключением того, что преобразование prvalue типа "указатель на T1" в тип "указатель на T2" (где T1 и T2 являются типами функций) и обратно к его исходному типу дает исходное значение указателя, результат такого преобразование указателя не указано. [Примечание: Смотрите также [conv.ptr] для более подробной информации о преобразованиях указателя. - конец примечания]

Мне кажется, что в этой заметке говорится, что следующий фрагмент (см. Демонстрацию) имеет неопределенное поведение. Это правильно? Или кроме этого есть что-то еще?

#include<iostream>
void f() { std::cout << "function returning void\n"; }
int g() { std::cout << "function returning int\n"; return 1; }

int main(){
    void (*pf)() = f;
    reinterpret_cast<int(*)()>(pf)();
}

1 ответ

Дело в том, что указатель функции может быть преобразован, но результат не может быть использован. Тем не менее, результат может быть преобразован обратно в исходный тип перед использованием. Идея состоит в том, чтобы хранить один из нескольких типов указателей на функции в одной переменной (без необходимости union) вместе с тегом, который указывает (каким-то образом) фактический тип функции.

Обратите внимание, что вы не можете переносить указатель функции на указатель объекта (например, void*) совсем. Тем не менее, POSIX предполагает, что вы можете сделать это, так что это очень часто работает.

Другие вопросы по тегам