C++ template-parameter specialization for nullptr pointer-to-member-function.
leon zadorin
leonleon77@gmail.com
Mon Nov 12 04:57:00 GMT 2018
The following question is in relation to GCC(8) behavior vs Clang(7) albeit
earlier versions of both also exhibit the same disparity.
This sample code:
#include <iostream>
struct Goo_t {
void Go() {
::std::cout << "Go" << ::std::endl;
}
};
typedef void (Goo_t::* Callback_T)();
template <typename Object_T, Callback_T Callback, bool = Callback ==
nullptr>
struct Invoker_t {
Invoker_t(Object_T * Object) {
::std::cout << "Invoking " << (Callback == nullptr) << ::std::endl;
(Object->*Callback)();
}
};
template <typename Object_T, Callback_T Callback>
struct Invoker_t<Object_T, Callback, true> {
Invoker_t(Object_T *) {
::std::cout << "Bypassing" << ::std::endl;
}
};
template <Callback_T Callback>
void Foo(Goo_t * Goo) {
(Invoker_t<Goo_t, Callback>)(Goo);
}
int main()
{
Goo_t Goo;
Foo<&Goo_t::Go>(&Goo);
Foo<nullptr>(&Goo);
}
GCC builds and runs ok, producing:
Invoking 0
Go
Bypassing
Whereas Clang yields segmentation fault with the following output:
Invoking 0
Go
Invoking 1
... then naturally causing Segmentation fault (appears to compile-time
select template which is conditioned on pointer being non-null for both
cases)
(experiments executed online at https://wandbox.org/ )
Moreover, Clang seems to be the odd one out as VisualC++(2017) also appears
to build/run ok... but I could be trippin... perhaps the code above has a
bug leading to undefined behavior which eventuates in segfault in Clang but
happens to be coincidentally tolerated by GCC? Or is the code valid?
More information about the Gcc-help
mailing list