|
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