Boost logo

Boost :

Subject: [boost] [local_function] how bad is this `static_cast<>`?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-09-09 09:45:03


Hello all,

How bad is the `static_cast<>` below?

struct c {
    void g() {}

    void f() {
        struct l: c { // Local function class wrapper.
            void body() {
                g(); // Usual implicit `this` access.
                this->g(); // Usual explicit `this` access.
            }
        };

        static_cast<l*>(this)->body(); // *** HOW BAD IS THIS
`STATIC_CAST<>`? ***
    }
};

Could Boost.LocalFunction internally use such a technique when a
special configuration macro is #defined by the users?

IMO, if this `static_cast<>` can really corrupt memory on some
systems/compilers, maybe Boost.LocalFunction should *never* use it.
Otherwise, what would the documentation say "WARNING: If you #define
this configuration macro, memory could be corrupted in some unknown
way on some unknown combination of systems/compilers..." -- it's like
providing a self-destruction button with a random countdown sequence
via the configuration macro! What do you think?

BACKGROUND

Boost.LocalFunction can internally use this `static_cast<>` to provide
access to the bound `this` parameter using the usual C++ syntax
instead of the special name `this_`:

#define BOOST_LOCAL_FUNCTION_CONFIG_IMPLICIT_THIS_HACK

#include <boost/local_function.hpp>

struct c {
    c(): x_(0.0) {}

    // Non-const member can bind `this` as non-const-bound.
    void f(double x) {
        double y = x + 10.0;

        BOOST_LOCAL_FUNCTION(
        (double) (total)( (int)(offset) (const bound)((&x)) (bound)((this)(y)) )
        ) {
            reset(); // (1) Implicit `this`.
            this->x_ = x; // (2) Explicit `this`.
            assert(this_->equal(x)); // Also `this_`.

            double tot = x + y + offset;
            return tot;
        } BOOST_LOCAL_FUNCTION_END(total)

        double tot = total(100.0);
        std::cout << tot << std::endl;
    }

    void reset() { x_ = 0.0; }
    bool equal(double x) const { return x_ == x; }

private:
    double x_;
};

But if `BOOST_LOCAL_FUNCTION_CONFIG_IMPLICIT_THIS_HACK` is left
#undefined (default) then line (1) and (2) must use `this_`:

            this_->reset();
            this_->x_ = x;

REFERENCE

This code was originally proposed to me by Anthony Williams in order
to access the outer class `this` object from within the local
function:

On Jul 29, 11:05 am, Anthony Williams <anthony...._at_[hidden]> wrote:
> Lorenzo Caminiti <lorcamin..._at_[hidden]> writes:
> > However, ideally the code expression passed to `BLOCK_INVARIANT()`
> > will looks the exactly the same as the code programmed within `f()`.
> > Therefore, `this_->eq(x)` will ideally be `this->eq(x)`. Is there a
> > way I can do this without inheriting `block_inv` from `c`? And that is
> > what I need.
>
> No, you cannot do that. "this" refers to an instance of the currentclass. Inside member functions of a localclass, "this" refers to an
> instance of that localclass.
>
> You can do it with a nasty (i.e. strictly undefined behaviour, but works
> in practice) hack though: if your localclasshas no data members and no
> virtual functions then you can derive the localclassfrom theouterclassand cast your "this" pointer to be an instance of the localclass:
>
> #include <iostream>
> class X
> {
> private:
>     void g() const
>     {
>         std::cout<<"g(), this="<<this<<std::endl;
>     }
> public:
>     void f()
>     {
>         std::cout<<"f(), this="<<this<<std::endl;
>         struct local:X
>         {
>             void foo() const
>             {
>                 this->g();
>             }
>         };
>
>         local const* p=static_cast<local const*>(const_cast<X
> const*>(this));
>         p->foo();
>     }
>
> };
>
> int main()
> {
>     X x;
>     x.f();
>
> }
>
> Anthony
> --
> Author of C++ Concurrency in Action    http://www.stdthread.co.uk/book/
> just::thread C++0x thread library            http://www.stdthread.co.uk
> Just Software Solutions Ltd      http://www.justsoftwaresolutions.co.uk
> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
>
>       [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
>       [ comp.lang.c++.moderated.    First time posters: Do this! ]

See: http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/d3a86f27277f713b

-- 
Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk