I am toying around with an old C++ callback implementation, presented in a paper by Rich Hickey. (See .html for reference.)
G++ 14.2 gives me a warning when compiling the following simplified code with g++ -c -Wall -O2
. The warning starts with G++ 11, older versions don't complain. The warning also goes away when using -O0
or -O1
.
#include <cstddef>
#include <cstring>
struct FunctorBase
{
typedef void (FunctorBase::*MethodPtr)();
template<typename Method>
Method get_method() const
{
return *static_cast<Method const*>(static_cast<void const*>(_method));
}
FunctorBase(const void* method, std::size_t sz) : _method{}
{
std::memcpy(_method, method, sz);
}
alignas (MethodPtr) unsigned char _method[sizeof(MethodPtr)];
};
template<class P1>
struct Functor1 : FunctorBase
{
typedef void (*Thunk)(const FunctorBase&, P1);
Functor1(Thunk t, const void* mf, size_t sz) : FunctorBase(mf, sz), thunk(t) {}
void operator()(P1 p1) const
{
thunk(*this, p1);
}
Thunk thunk;
};
template<class Callee, class Method>
struct MemberOf1stArgTranslator1 : Functor1<Callee>
{
MemberOf1stArgTranslator1(const Method& m) : Functor1<Callee>(thunk, &m, sizeof(Method)) {}
static void thunk(const FunctorBase& ftor, Callee callee)
{
(callee.*ftor.get_method<Method>())();
}
};
template<class P1, class TRT, class CallType>
inline MemberOf1stArgTranslator1<P1, TRT (CallType::*)()> create_functor(Functor1<P1>*, TRT (CallType::*const& f)())
{
typedef TRT (CallType::*Method)();
return MemberOf1stArgTranslator1<P1, Method>(f);
}
struct MyCallee
{
void my_f() {}
};
void f()
{
typedef Functor1<MyCallee&> F;
F f = create_functor((F*)0, &MyCallee::my_f);
MyCallee c;
f(c);
}
The reported warning is:
In static member function 'static void MemberOf1stArgTranslator1<Callee, Method>::thunk(const FunctorBase&, Callee) [with Callee = MyCallee&; Method = void (MyCallee::*)()]',
inlined from 'void Functor1<P1>::operator()(P1) const [with P1 = MyCallee&]' at <source>:31:7,
inlined from 'void f()' at <source>:65:5:
<source>:44:42: warning: array subscript 'int (**)(...)[0]' is partly outside array bounds of 'MyCallee [1]' [-Warray-bounds=]
44 | (callee.*ftor.get_method<Method>())();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
<source>: In function 'void f()':
<source>:64:13: note: object 'c' of size 1
64 | MyCallee c;
| ^
I have a hard time understanding this warning, as there is no array of MyCallee
objects.
What is the compiler trying to tell me here? Is it a real concern with the code or is the warning spurious?