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