Date: Sat, 16 Apr 2022 22:42:15 +0100
On Sat, Apr 16, 2022 at 7:28 PM, Thiago Macieira via Std-Proposals wrote:
> > union {
> > void (*f)(void);
> > bool (Base::*m)(void);
> > } const fm = { _method };
>
> Because you're not supposed to do this.
>
> Your code is UB and WILL FAIL on some architectures or with some objects
> because you failed to set up the other half of the PMF properly.
I've only looked more closely at method pointers for the first time
today -- I didn't realise that they could perform virtual calls, I
thought they were just a pointer to a function that had a hidden first
parameter (i.e. 'this').
Anyway after thinking a bit more about this, I realise that I don't
even need function pointers at all. I've changed the code as follows:
template<class Base, class Derived>
class MethodInvoker final : public IMethodInvoker {
protected:
bool Trigger(void *const arg_this) override
{
Base *const p = static_cast<Base*>(static_cast<Derived*>(arg_this));
return p->Base::Trigger(); // NO NEED FOR FUNC PTR HERE
}
void Elevate(void *const arg_this, float const arg0) override
{
Base *const p = static_cast<Base*>(static_cast<Derived*>(arg_this));
return p->Base::Elevate(arg0); // NO NEED FOR FUNC PTR HERE
}
};
You can see the entire code change in my Github commit here:
https://github.com/healytpk/continuity_methods/commit/36b24ad84b114d6937f4b97759e73b2231b49b25#diff-451b592c332a4930ebcad7c112542e381f8b5296034c218b6c38cd09a3b87a48
> > union {
> > void (*f)(void);
> > bool (Base::*m)(void);
> > } const fm = { _method };
>
> Because you're not supposed to do this.
>
> Your code is UB and WILL FAIL on some architectures or with some objects
> because you failed to set up the other half of the PMF properly.
I've only looked more closely at method pointers for the first time
today -- I didn't realise that they could perform virtual calls, I
thought they were just a pointer to a function that had a hidden first
parameter (i.e. 'this').
Anyway after thinking a bit more about this, I realise that I don't
even need function pointers at all. I've changed the code as follows:
template<class Base, class Derived>
class MethodInvoker final : public IMethodInvoker {
protected:
bool Trigger(void *const arg_this) override
{
Base *const p = static_cast<Base*>(static_cast<Derived*>(arg_this));
return p->Base::Trigger(); // NO NEED FOR FUNC PTR HERE
}
void Elevate(void *const arg_this, float const arg0) override
{
Base *const p = static_cast<Base*>(static_cast<Derived*>(arg_this));
return p->Base::Elevate(arg0); // NO NEED FOR FUNC PTR HERE
}
};
You can see the entire code change in my Github commit here:
https://github.com/healytpk/continuity_methods/commit/36b24ad84b114d6937f4b97759e73b2231b49b25#diff-451b592c332a4930ebcad7c112542e381f8b5296034c218b6c38cd09a3b87a48
Received on 2022-04-16 21:42:26