Что означает примечание ниже в [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 предполагает, что вы можете сделать это, так что это очень часто работает.