Re: class variables: scoping
"Neil Zanella" <nzanella@cs.mu n.ca> wrote in message[color=blue]
> "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message[/color]
news:<7Orcc.259 11
[color=blue][color=green]
> > /*mutable*/ std::set<std::s tring> d_constructed;
> >
> > and in your functions use the __FUNCTION__ macro to indicate that the
> > variables of this function are constructed. Note that __FUNCTION__ is[/color][/color]
not[color=blue][color=green]
> > standard, though there are variations you can try.[/color][/color]
[color=blue]
> Is the __FUNCTION__ macro specific to the gcc compiler suite or does it[/color]
work[color=blue]
> with other compilers as well. In any case standard behavior could be[/color]
attained[color=blue]
> by using an enumeration with something similar to function names in it.[/color]
Borland 6 does not support __FUNCTION__. I think Microsoft does, but ask on
a Microsoft group to be sure, or try it on the compiler.
Instead of maintaining an enum, I was thinking of converting the address of
a function to a string, like this,
void * ptr = static_cast<voi d *>(&X::function );
std::cout << ptr;
But you can't convert a pointer to member function into a void*, even
through reinterpret_cas t, because they usually have different sizes. And
typeid(&X::func tion).name() prints the type of the function, so if
X::function1 and X::function2 have the same signature, typeid.name() prints
the same thing.
To avoid cluttering the header file, why not just use the pointer to
implementation idea where you declare the struct in the cpp file? You get
insulation for free, can use reference counted smart pointers if so desired
(though they have multi-threading problems/challenges too), etc.
[color=blue][color=green]
> > The static variables idea in your previous post works could easily cause
> > trouble in multi-threaded environments.[/color]
>
> Perhaps you are referring to the fact that in a multithreaded applications
> two objects may have the same virtual address, hence it is not possible to
> identify an object on the basis of its virtual address and be certain that
> the application will work. Is this what you are referring to when you[/color]
mention[color=blue]
> that problems may arise in multithreaded applications.[/color]
It's the standard one. Two threads call your function X::f(). Both see
that the static variable is not constructed. Then both go ahead and
construct it.
The solution is when one thread sees it is not constructed it blocks the
function memory so the other thread cannot do anything, the the first thread
constructs the object and releases the block, and the other thread then sees
the static variable is constructed. There is no native support for this in
C++. You have to use OS functions like critical section and mutexes. Even
if it works, the use of these OS functions is quite expensive. I'm not an
expert on multi-threading (still learning it myself), but those are the
basics.
"Neil Zanella" <nzanella@cs.mu n.ca> wrote in message[color=blue]
> "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message[/color]
news:<7Orcc.259 11
[color=blue][color=green]
> > /*mutable*/ std::set<std::s tring> d_constructed;
> >
> > and in your functions use the __FUNCTION__ macro to indicate that the
> > variables of this function are constructed. Note that __FUNCTION__ is[/color][/color]
not[color=blue][color=green]
> > standard, though there are variations you can try.[/color][/color]
[color=blue]
> Is the __FUNCTION__ macro specific to the gcc compiler suite or does it[/color]
work[color=blue]
> with other compilers as well. In any case standard behavior could be[/color]
attained[color=blue]
> by using an enumeration with something similar to function names in it.[/color]
Borland 6 does not support __FUNCTION__. I think Microsoft does, but ask on
a Microsoft group to be sure, or try it on the compiler.
Instead of maintaining an enum, I was thinking of converting the address of
a function to a string, like this,
void * ptr = static_cast<voi d *>(&X::function );
std::cout << ptr;
But you can't convert a pointer to member function into a void*, even
through reinterpret_cas t, because they usually have different sizes. And
typeid(&X::func tion).name() prints the type of the function, so if
X::function1 and X::function2 have the same signature, typeid.name() prints
the same thing.
To avoid cluttering the header file, why not just use the pointer to
implementation idea where you declare the struct in the cpp file? You get
insulation for free, can use reference counted smart pointers if so desired
(though they have multi-threading problems/challenges too), etc.
[color=blue][color=green]
> > The static variables idea in your previous post works could easily cause
> > trouble in multi-threaded environments.[/color]
>
> Perhaps you are referring to the fact that in a multithreaded applications
> two objects may have the same virtual address, hence it is not possible to
> identify an object on the basis of its virtual address and be certain that
> the application will work. Is this what you are referring to when you[/color]
mention[color=blue]
> that problems may arise in multithreaded applications.[/color]
It's the standard one. Two threads call your function X::f(). Both see
that the static variable is not constructed. Then both go ahead and
construct it.
The solution is when one thread sees it is not constructed it blocks the
function memory so the other thread cannot do anything, the the first thread
constructs the object and releases the block, and the other thread then sees
the static variable is constructed. There is no native support for this in
C++. You have to use OS functions like critical section and mutexes. Even
if it works, the use of these OS functions is quite expensive. I'm not an
expert on multi-threading (still learning it myself), but those are the
basics.
Comment