By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,199 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

construction of static foo objects .. more

P: n/a
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() ;

}

Sep 28 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a

ma740988 wrote:
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

Sep 28 '06 #2

P: n/a

Alan Johnson wrote:
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?
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.

Sep 28 '06 #3

P: n/a
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
Sep 28 '06 #4

P: n/a
ma740988 <ma******@gmail.comwrote:
>Alan Johnson wrote:
>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?
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
Sep 28 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.