Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Static variable in static library: bug???



Hi,
I got a serious problem with static variables and I need some
explanation and/or advice about what to do. Maybe it is my mistake or I
miss
something, or there is some conceptual problem in actual c++
compilers.

The situation is the following (code is attached): 
I have 1 parent class: ChangeManager
Multiple derived classes: SimpleChangeManager, NullChangeManager
(whatever else you want).
The parent contains a list of all the derived classes: they are
registered into the parent in a static registry (s_registry), via a
static method called ChangeManager::RegisterManager(string name,
ChangeManager* manager).
ChangeManager is not fully implemented (it has a method that is pure
virtual), so you cannot use any object of kind ChangeManager.

For having the registration of object of the derived classes without
really referring 
to them, is done in this neat way:
1) you do the registration inside the constructor of the derived class
2) you create a static variable inside the cpp file containing the
implementation of the derived class.
In this way no one know about that variable. No one knows about that
class except the ChangeManager.

In practice I have:
SimpleChangeManager() {
   ChangeManager::RegisterManager("SimpleManager", this);
}

When I want to access the registered object I do the following:
Somewhere and I don't care where I do
ChangeManager::Activate("SimpleManager");
This will set an internal static variable in ChangeManager

I want to use the active change manager I do
ChangeManager::Instance()

Everything seems fine, no tricks or weird stuff.

The problem:
a) if I create a single executable with the attached code everything
goes fine. Both NullChangeManager and SimpleChangeManager are
registered correctly.
b) if I create a shared library everything goes fine as well
c) if I create a STATIC library then none is Registered
Why??
A clue: if in the main you do
ChangeManager* manager = new SimpleChangeManager();
then that maneger is registered twice: the one that is static inside
the cpp code, and the one that you just created.

This weird behavior is obtained in Linux (gcc 2.7.2.3, gcc 2.95),
SunOS (gcc 2.95), HPUX (gcc 2.95, HP aC++ A.01.00 ) 

Anyone of you can explain me that?? Is it a bug in the compiler? Is it
a bug somewhere else???

Thanks

Max

Here is the result on Linux RH5.1 gcc 2.95
--------------------------------------------------------------------------------
Static Library
--------------------------------------------------------------------------------
[mmorin at jupiter tmp]> make
g++ -c -pipe -g  -o ChangeManager.o ChangeManager.cpp
g++ -c -pipe -g  -o NullChangeManager.o NullChangeManager.cpp
g++ -c -pipe -g  -o SimpleChangeManager.o SimpleChangeManager.cpp
rm -f libtest.a
ar cqs libtest.a ChangeManager.o NullChangeManager.o
SimpleChangeManager.o 
[mmorin at jupiter tmp]> g++ -o Test main.cpp -L. -ltest
[mmorin at jupiter tmp]> Test
Start
Test: ChangeManager.cpp:125: static class ChangeManager *
ChangeManager::Lookup(const char *): Assertion `s_registry != __null'
failed.
Aborted
[mmorin at jupiter tmp]>  
--------------------------------------------------------------------------------
Shared ibrary
--------------------------------------------------------------------------------
[mmorin at jupiter tmp]> make
g++ -c -pipe -g -fPIC  -o ChangeManager.o ChangeManager.cpp
g++ -c -pipe -g -fPIC  -o NullChangeManager.o NullChangeManager.cpp
g++ -c -pipe -g -fPIC  -o SimpleChangeManager.o SimpleChangeManager.cpp
rm -f libtest.so.1.0 libtest.so libtest.so.1
g++ -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 ChangeManager.o
NullChangeManager.o SimpleChangeManager.o  
ln -s libtest.so.1.0 libtest.so
ln -s libtest.so.1.0 libtest.so.1
[mmorin at jupiter tmp]> g++ -o Test main.cpp -L. -ltest
[mmorin at jupiter tmp]> Test
CALEED
Change Manager SimpleManager -> 0x4003bf1c
Change Manager NullManager -> 0x4003bf18
Start
This is notify of NULL CHANGE MANAGER
That is all!
[mmorin at jupiter tmp]> 

-- 
  Massimo Morin                                _...__..-'
mmorin at schedsys.com                          .'
 (617) 484 2999 h                          .'
 (617) 512 0203 c                        .'   Airline 
                                       .'    Solutions 
            .------._                 ;        Today
      .-"""`-.<')    `-._           .'     
     (.--. _   `._       `'---.__.-'
      `   `;'-.-'         '-    ._     Scheduling Systems Inc.
        .--'``  '._      - '   .       Three University Office Park
         `""'-.    `---'    ,          95 Sawyer Road
 ''--..__      `\                      Waltham, 02453 Massachusetts USA
         ``''---'`\      .'            +1 (781) 893-0390 x 126
                   `'. '               http://www.schedsys.com
Software Engineer    `'.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: staticLibProblem.tgz
Type: application/octet-stream
Size: 3080 bytes
Desc: not available
URL: <http://lists.blu.org/pipermail/discuss/attachments/20000225/071832d3/attachment.obj>



BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org