
September 28th, 2006, 02:15 AM
| | | construction of static foo objects .. more
Referencing source snippet below, the actual contruction of the foo
objects is done in a class. In that regard, I chose methods,
class1_construct and class2_construct for demonstration purposes. That
aside, I encountered source akin to what's shown below today and I was
almost convinced the source is wrought with trouble. On second thought
it appears legal. The static ptr_foo object and it's use in assignment
to other foo objects (ptr_1 etc ) at first troubled me but it's fine as
is. Correct? Of course the real issue surrounded the fact that the
ptr_1, ptr_2, ptr_3 and ptr_4 objects ar used in a thread. As a result
when the user exited the GUI application the vector of foo objects ( fv
vec ) was being called prior to destruction of the ptr_1, ptr_2 , ptr_3
and ptr_4 objects. That led to nasty error messages.
My initial recommendation (futher below )was to rid the 'statics', in
part because I thought there was a static initilization/destruction
fiasco going on. Come to think of it that's not the case. Correct?
Having said I think the ideal thing to do here involves the use of a
reference counted smart pointer. Correct?
# include <vector>
# include <sstream>
# include <string>
std::string
to_string(int i)
{
std::stringstream s;
s << i;
return s.str() ;
}
struct foo {
std::string str ;
};
typedef std::vector < foo* foo_vec ;
foo_vec fv;
void class1_construct()
{
for ( int idx ( 0 ); idx < 4; ++idx )
{
foo *ptr_foo = new foo () ;
ptr_foo->str = to_string ( idx ) ;
fv.push_back ( ptr_foo ) ;
}
}
void class1_delete()
{
for ( foo_vec::size_type idx ( 0 );
idx < fv.size();
++idx )
{
std::cout << "delete " << std::endl;
delete fv [ idx ] ;
}
}
static foo *ptr_foo;
static foo *ptr_1;
static foo *ptr_2;
static foo *ptr_3;
static foo *ptr_4;
int main()
{
class1_construct() ;
for ( foo_vec::size_type idx ( 0 );
idx < fv.size();
++idx )
{
ptr_foo = fv [ idx ];
if ( ptr_foo->str == "1" )
{
ptr_1 = ptr_foo ;
}
if ( ptr_foo->str == "2" )
{
ptr_2 = ptr_foo ;
}
if ( ptr_foo->str == "3" )
{
ptr_3 = ptr_foo ;
}
if ( ptr_foo->str == "4" )
{
ptr_4 = ptr_foo ;
}
}
class1_delete() ;
}
Initial recommendation
foo *ptr_1;
foo *ptr_2;
foo *ptr_3;
foo *ptr_4;
int main()
{
class1_construct() ;
for ( foo_vec::size_type idx ( 0 );
idx < fv.size();
++idx )
{
foo *ptr_foo = fv [ idx ];
if ( ptr_foo->str == "1" )
{
ptr_1 = ptr_foo ;
}
if ( ptr_foo->str == "2" )
{
ptr_2 = ptr_foo ;
}
if ( ptr_foo->str == "3" )
{
ptr_3 = ptr_foo ;
}
if ( ptr_foo->str == "4" )
{
ptr_4 = ptr_foo ;
}
}
class1_delete() ;
} | 
September 28th, 2006, 02:45 AM
| | | Re: construction of static foo objects .. more
ma740988 wrote: Quote:
Referencing source snippet below, the actual contruction of the foo
objects is done in a class. In that regard, I chose methods,
class1_construct and class2_construct for demonstration purposes. That
aside, I encountered source akin to what's shown below today and I was
almost convinced the source is wrought with trouble. On second thought
it appears legal. The static ptr_foo object and it's use in assignment
to other foo objects (ptr_1 etc ) at first troubled me but it's fine as
is. Correct? Of course the real issue surrounded the fact that the
ptr_1, ptr_2, ptr_3 and ptr_4 objects ar used in a thread. As a result
when the user exited the GUI application the vector of foo objects ( fv
vec ) was being called prior to destruction of the ptr_1, ptr_2 , ptr_3
and ptr_4 objects. That led to nasty error messages.
>
My initial recommendation (futher below )was to rid the 'statics', in
part because I thought there was a static initilization/destruction
fiasco going on. Come to think of it that's not the case. Correct?
Having said I think the ideal thing to do here involves the use of a
reference counted smart pointer. Correct?
| At global scope, the "static" keyword affects linkage, not lifetime, so
a static initialization/destruction fiasco would not be affected. The
only thing that changes when you remove the "static" keyword from
ptr_1, ptr_2, ptr_3, and ptr_4 is that now they may be referenced by
another translation unit (one that declares them with something like
"extern foo *ptr_1;").
In a quick examination, I don't see anything wrong with the code you
posted, with or without the statics. Does it cause some error on your
system?
--
Alan Johnson | 
September 28th, 2006, 03:15 AM
| | | Re: construction of static foo objects .. more
Alan Johnson wrote: Quote:
At global scope, the "static" keyword affects linkage, not lifetime, so
a static initialization/destruction fiasco would not be affected. The
only thing that changes when you remove the "static" keyword from
ptr_1, ptr_2, ptr_3, and ptr_4 is that now they may be referenced by
another translation unit (one that declares them with something like
"extern foo *ptr_1;").
| Perhaps I'm mistaken (time to brush up again) but I thought the ones
with the static keyword could also be referenced in another translation
unit, except now I don't need extern? Quote:
In a quick examination, I don't see anything wrong with the code you
posted, with or without the statics. Does it cause some error on your
system?
| Well there's a piece that I may or may not have mentioned, which
involved the desctruction of the vector on exit. ptr_1, ptr_2, ptr_3
and ptr_4 was used in a thread and from the looks of it the vector of
objects was destroyed prior to deleting the thread. As a result I was
seeing alot of 'undefined behavior ( crash) ' errors. | 
September 28th, 2006, 03:55 AM
| | | Re: construction of static foo objects .. more
This is a bit of a tangent, but is it typical and/or correct
to refer to a function like class1_construct() as a constructor?
To me it's not a constructor but a global function, not part of any
class, operating on a free-floating object.
Steve | 
September 28th, 2006, 04:15 AM
| | | Re: construction of static foo objects .. more
ma740988 <ma740988@gmail.comwrote: Quote: Quote:
>At global scope, the "static" keyword affects linkage, not
>lifetime, so a static initialization/destruction fiasco would not
>be affected. The only thing that changes when you remove the
>"static" keyword from ptr_1, ptr_2, ptr_3, and ptr_4 is that
>now they may be referenced by another translation unit (one
>that declares them with something like "extern foo *ptr_1;").
| | Quote:
>Perhaps I'm mistaken (time to brush up again) but I thought the ones
>with the static keyword could also be referenced in another translation
>unit, except now I don't need extern?
| What Alan said -- static at global scope is a holdover from C,
deprecated in C++, which makes the name invisible to other translation
units. If you have "static int foo" in one translation unit and
"extern int foo" in a second translation unit, they will never
reference the same variable. (And you will need a plain "int foo"
somewhere for the extern to resolve.)
Officially, you should now use a nameless namespace to make a name
visible in only one translation unit, instead of global "static".
Steve |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over network members.
|