В языке нет другого способа привести тип указателя функции к типу указателя объекта, кроме reinterpret_cast
. Это определяется поведением, определенным реализацией [expr.reinterpret.cast] / 8 :
Преобразование указателя функции в тип указателя объекта или наоборот поддерживается условно. Смысл такого преобразования определяется реализацией, за исключением того, что если реализация поддерживает преобразования в обоих направлениях, преобразование prvalue одного типа в другой тип и обратно, возможно, с другой квалификацией cv, должно давать исходное значение указателя.
Это означает, что соответствующий компилятор C ++ должен документ, если он не поддерживает эту функцию. И, если он это поддерживает, он должен задокументировать, как именно он себя ведет. Вы можете положиться на то, что он работает (или не доступен) задокументированным способом на этом компиляторе.
Относительно основных руководящих принципов: Если вам нужно поставить //NOLINT
"везде", то это может означать, что вы называете голым dlsym()
во многих местах. Попробуйте обернуть его, например
template <typename T>
inline T* lookupSymbol(void* module, const char* name)
{
auto symbol = reinterpret_cast<T*>(dlsym(module, name)); // NOLINT
if (!symbol)
throw std::runtime_error("failed to find symbol '"s + name + '\'');
return symbol;
}