f



Working with static member before main

Here is some program and run results.

===========================================
Windows 2000
CYGWIN_NT-5.0 1.3.22(0.78/3/2)
GNU gcc version 3.2 20020927 (prerelease)
===========================================

========= C++ code : BEGIN =========
// File t.cpp
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;


class Foo
{
  private :
    string   name_;
    static vector<string> names_s;
  public :
    Foo (const string& name_i);
    ~Foo ();
    static void show_s ();
};

Foo a("AAA");
Foo b("BBB");

vector<string> Foo::names_s;

Foo c("CCC");
Foo d("DDD");
Foo e("EEE");


Foo::Foo(const string& name_i) : name_ (name_i)
{
  names_s.push_back(name_);
  show_s ();
}

Foo::~Foo()
{
}


void Foo::show_s ()
{
  copy (names_s.begin(), names_s.end(), ostream_iterator<string>(cout, "
"));
  cout << endl;
}


int main()
{
  cout << endl << "--- main ---" << endl;
  Foo::show_s ();

  return 0;
}

========= C++ code : END ===========


========= Compilation & Run : BEGIN =========

$ g++ t.cpp

$ a

AAA
AAA BBB
CCC
CCC DDD
CCC DDD EEE

--- main ---
CCC DDD EEE

========= Compilation & Run : END ===========


Why are "AAA" and "BBB" are written to names_s
  before nname_s' initialization?

Are really there two names_s's :
* temporary which contains "AAA" and "BBB"
  and
* permanent which contains "CCC", "DDD" and "EEE"?


   ==========================================
   Alex Vinokur
     mailto:alexvn@connect.to
     http://www.simtel.net/pub/oth/19088.html
     http://sourceforge.net/users/alexvn
   ==========================================





      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Alex
6/26/2003 7:37:31 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

1 Replies
648 Views

Similar Articles

[PageSpeed] 31

"Alex Vinokur" <alexvn@bigfoot.com> wrote in message
news:<bdf793$rt81v$1@ID-79865.news.dfncis.de>...
> Here is some program and run results.

> ===========================================
> Windows 2000
> CYGWIN_NT-5.0 1.3.22(0.78/3/2)
> GNU gcc version 3.2 20020927 (prerelease)
> ===========================================

> ========= C++ code : BEGIN =========
> // File t.cpp
> #include <string>
> #include <vector>
> #include <iostream>
> #include <iterator>
> using namespace std;

> class Foo
> {
>   private :
>     string   name_;
>     static vector<string> names_s;
>   public :
>     Foo (const string& name_i);
>     ~Foo ();
>     static void show_s ();
> };

> Foo a("AAA");
> Foo b("BBB");

> vector<string> Foo::names_s;

Attention: within a translation unit, the order of initialization
corresponds to the order of definition.  Thus, Foo::names_s will NOT be
constructed until the global variables a and b are constructed.  Since
the constructor for Foo uses this variable, you have undefined behavior.

> Foo c("CCC");
> Foo d("DDD");
> Foo e("EEE");

> Foo::Foo(const string& name_i) : name_ (name_i)
> {
>   names_s.push_back(name_);
>   show_s ();
> }

> Foo::~Foo()
> {
> }

> void Foo::show_s ()
> {
>   copy (names_s.begin(), names_s.end(), ostream_iterator<string>(cout, "
> "));
>   cout << endl;
> }

> int main()
> {
>   cout << endl << "--- main ---" << endl;
>   Foo::show_s ();

>   return 0;
> }

> ========= C++ code : END ===========

> ========= Compilation & Run : BEGIN =========

> $ g++ t.cpp

> $ a

> AAA
> AAA BBB
> CCC
> CCC DDD
> CCC DDD EEE

> --- main ---
> CCC DDD EEE

> ========= Compilation & Run : END ===========

> Why are "AAA" and "BBB" are written to names_s
>   before nname_s' initialization?

Because the standard says that they should be.  Why shouldn't they be?

> Are really there two names_s's :
> * temporary which contains "AAA" and "BBB"
>   and
> * permanent which contains "CCC", "DDD" and "EEE"?

No.  Variables with static life spans are zero initialized before any
dynamic initialization starts.  It just so happens that in the case of
std::vector, at least in your implementation, zero initialization
corresponds to construction with the default constructor.  (This is the
case in most implementations of std::vector, I think.)  So the code in
the constructors for a and b works.  Then the constructor for names_s is
called; it overwrites whatever was previously in the object with an
initialization which says that the vector is empty.

If you run this program under Purify, you will probably see that it
reports memory leaks.  The reason is simple: the push_back in the
constructor for a has allocated memory, which is lost when the
constructor for names_s overwrites the memory.

--
James Kanze             GABI Software             mailto:kanze@gabi-soft.fr
Conseils en informatique orient�e objet/
                           Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T�l. : +33 (0)1 30 23 45 16

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
kanze
6/27/2003 2:01:45 PM
Reply: