[bt-devel] namespace problems

David White bt-devel@crosswire.org
20 Oct 2002 06:46:47 +1000


Joachim,

If you have a constant in C++ that is shared across multiple translation
units (i.e. source files), you must declare it in the header file, but
define it in the source file.

i.e. in the header file, you will have:

extern const QString tooltip;

while in the source file you will have:

const QString tooltip = makeToolTip( i18n("Clear the printing queue") );

This is because you want the symbol to be shared among many source
files, so you have to put a declaration in the header file, but the C++
"One Definition Rule" states that a symbol can only be defined once,
across all translation units, and so you may not put the definition in a
header file - only a source file.

You will obviously need the namespace structure reflected in both the
source file and the header file.

Yes, it is a little annoying having to do this, and it does make one
wish that C++ had a real module system, but it doesn't, so we have to
live with what we've got.

Let me know if you need anymore help.

-David.


On Sun, 2002-10-20 at 06:34, Joachim Ansorg wrote:
> David White, I think this eMail is especially for you because you know the 
> namespaces well.
> 
> You pointed me into the direction to use namespaces for the treelike structure 
> I wanted.
> 
> Now I have something like
> 
> namespace CResMgr {
>   inline const QString makeToolTip( const QString& text ) {
>     return text;
>   };
>   inline const QString makeWhatsThis( const QString& title, const QString& 
> description )  {
>     return 
> QString::fromLatin1("<center><B>%1</B></center><HR>%2").arg(title).arg(description);
>   };
> 
>   namespace mainMenu { //Main menu
>     namespace file { //Main menu->File
>       namespace clearQueue {
>         const QString tooltip     = makeToolTip( i18n("Clear the printing 
> queue") );
>         const QString whatsthis   = makeWhatsThis( tooltip, i18n("Clear the 
> print queue of BibleTime. All items will be removed from the list and the 
> print button will be disabled.") );
>         const QString icon        = QString::fromLatin1("queue");
>         const KShortcut accel     = KShortcut();
>         const char* actionName    = "fileClearQueue_action";
>       }
>       namespace print { //a standard action
>         const QString tooltip     = makeToolTip( i18n("Open the 
> printerdialog") );
>         const QString whatsthis   = makeWhatsThis( tooltip, i18n("Open the 
> printer dialog of BibleTime.  Here you can edit the print queue and assign 
> styles to the items.") );
>       }      
>       namespace quit { //a standard action
>         const QString tooltip     = makeToolTip( i18n("Close BibleTime") );
>         const QString whatsthis   = makeWhatsThis( tooltip, i18n("Close 
> BibleTime and save the settings.") );
>       }
>     }
> }
> etc.
> 
> But compiling BibleTime with this header included in two or more places I get 
> the following compiler warnings about multiple symbol definitions:
> 
> ./frontend/searchdialog/libsearchdialog.a(csearchdialog.o)(.data+0x0): 
> multiple definition of `CResMgr::mainMenu::file::clearQueue::actionName' 
> bibletime_init.o(.data+0x0): first defined here 
> ./frontend/searchdialog/libsearchdialog.a(csearchdialog.o)(.data+0x4): 
> multiple definition of `CResMgr::mainMenu::view::showMainIndex::actionName' 
> bibletime_init.o(.data+0x4): first defined here 
> ./frontend/searchdialog/libsearchdialog.a(csearchdialog.o)(.data+0x8): 
> multiple definition of `CResMgr::mainMenu::mainIndex::search::actionName' 
> bibletime_init.o(.data+0x8): first defined here 
> ./frontend/searchdialog/libsearchdialog.a(csearchdialog.o)(.data+0xc): 
> multiple definition of `CResMgr::mainMenu::window::loadProfile::actionName' 
> bibletime_init.o(.data+0xc): first defined here 
> 
> How can I avoid these problems? I have no idea.
> Thank you very much for any help!
> -- 
> Joachim Ansorg
> www.bibletime.de
> www.ansorgs.de