On 09/28/2017 05:23 AM, Pedro Alves wrote:
On 09/25/2017 02:03 AM, Martin Sebor wrote:
+a @option{-Wincompatible-pointer-types} warning for mismatches. To suppress
+a warning for the necessary cast from a pointer to the implementation member
+function to the type of the corresponding non-member function use the
+@option{-Wno-pmf-conversions} option. For example:
FWIW, it seems odd to me to tell users they need to suppress warnings, when
the compiler surely could provide better/safer means to avoid needing
to use the reinterpret_cast hammer. See below.
+
+@smallexample
+class S
+@{
+private:
+ int debug_impl (int);
+ int optimized_impl (int);
+
+ typedef int Func (S*, int);
+
+ static Func* resolver ();
+public:
+
+ int interface (int);
+@};
+
+int S::debug_impl (int) @{ /* @r{@dots{}} */ @}
+int S::optimized_impl (int) @{ /* @r{@dots{}} */ @}
+
+S::Func* S::resolver ()
+@{
+ int (S::*pimpl) (int)
+ = getenv ("DEBUG") ? &S::debug_impl : &S::optimized_impl;
+
+ // Cast triggers -Wno-pmf-conversions.
+ return reinterpret_cast<Func*>(pimpl);
+@}
+
If I were writing code like this, I'd write a reinterpret_cast-like
function specifically for pointer-to-member-function to free-function
casting, and only suppress the warning there instead of disabling
the warning for the whole translation unit. Something like:
#include <type_traits>
template<typename T> struct pmf_as_func;
template<typename Ret, typename S, typename... Args>
struct pmf_as_func<Ret (S::*) (Args...)>
{
typedef Ret (func_type) (S *, Args...);
typedef S struct_type;
};
template<typename Pmf>
typename pmf_as_func<Pmf>::func_type *
pmf_as_func_cast (Pmf pmf)
{
static_assert (!std::is_polymorphic<typename
pmf_as_func<Pmf>::struct_type>::value,
"");
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpmf-conversions"
return reinterpret_cast<typename pmf_as_func<Pmf>::func_type *> (pmf);
#pragma GCC diagnostic pop
}
and then write:
return pmf_as_func_cast (pimpl);
instead of:
return reinterpret_cast<Func*>(pimpl);
The point being of course to make it harder to misuse the casts.
But that may be a bit too much for the manual.
Yes, that's a much nicer solution but as you say, more code than
the manual typically includes for warnings. (It would be a good
example for a Users Guide if GCC had one.)
It also wouldn't work as is with C++03 (because variatic templates).
Which leads me to think that if GCC guarantees this cast works, then
it'd be nice to have GCC provide it (like a __pmf_as_func_cast function)
as builtin. Then it'd work on C++03 as well, and the compiler of course
can precisely validate whether the cast is valid. (It's quite possible
that there's a better check than is_polymorphic as I've written above.)
I also don't like the cast and have been thinking about how to
suppress the warning in this case (the ifunc resolver). But
the only way I can think to make it possible is to defer
-Wno-pmf-conversions until after all function declarations in
the translation unit have been processed. In other words, run
it in a separate pass and suppress it for functions that have
been aliased via attribute ifunc. I don't know if there already
is a pass like that it could be hooked into. If there is, it
should be feasible.
Nathan or Jason, is there something like this?
Martin