#include nightmare
-
Hi all, whenever i need some symbols/constants to be avairable to my entire application (all its files i mean), i create a header file (appconsts.h), and i #include it in each .cpp file of my application. this always worked fine, till recently, i recived some advice to stop using macros (#define) to define constants, and started using const, so (in my current project) i happily went to my appconsts.h file, and changed it like this (an example): Before: #if !defined(APPCONSTS_H) #define APPCONSTS_H #define MY_STRING _T("a string") #define MY_NUMBER 100 enum MY_ENUM{En1=0, En2, En3}; #endif AFTER: #if !defined(APPCONSTS_H) #define APPCONSTS_H const TCHAR* MY_STRING = _T("a string"); const int MY_NUMBER = 100; enum MY_ENUM{En1=0, En2, En3}; #endif its all very nice, the only problem is that i now get 708 errors (yes 708), about MY_STRING and MY_NUMBER allready being defined in another object. for example: ClientEditDlg.obj : error LNK2005: "char const * const COLHT_VLV_NOTES" (?COLHT_VLV_NOTES@@3PBDB) already defined in Boletaje.obj onfigSheet.obj : error LNK2005: "char const * const IF_FILENAME" (?IF_FILENAME@@3PBDB) already defined in Boletaje.obj please notice that i DID include guards on the appconsts.h file, i tried removing all the #includes to appconsts.h file, and just including it in my stdafx.h file, but no luck, and since this is a WTL project, i dont have any other file (besides stdafx.h) that gets included everywhere. Can someone help me out? ***UPDATE*** mhh, i get it now, i should declare the consts in some .cpp file (say where my winmain()is), and then op appconsts.h i should do like this: extern const TCHAR* MY_STRING = _T("a string"); extern const int MY_NUMBER = 100; enum MY_ENUM{En1=0, En2, En3}; is this correct? if so, wouldnt be easyer to just use #define instead of const? i mean, MS uses it! for example in winuser.h: // ShowWindow() Commands #define SW_HIDE 0 #define SW_SHOWNORMAL 1 #define SW_NORMAL 1 #define SW_SHOWMINIMIZED 2 #define SW_SHOWMAXIMIZED 3 #define SW_MAXIMIZE 3 ... what you guys think?
-
Hi all, whenever i need some symbols/constants to be avairable to my entire application (all its files i mean), i create a header file (appconsts.h), and i #include it in each .cpp file of my application. this always worked fine, till recently, i recived some advice to stop using macros (#define) to define constants, and started using const, so (in my current project) i happily went to my appconsts.h file, and changed it like this (an example): Before: #if !defined(APPCONSTS_H) #define APPCONSTS_H #define MY_STRING _T("a string") #define MY_NUMBER 100 enum MY_ENUM{En1=0, En2, En3}; #endif AFTER: #if !defined(APPCONSTS_H) #define APPCONSTS_H const TCHAR* MY_STRING = _T("a string"); const int MY_NUMBER = 100; enum MY_ENUM{En1=0, En2, En3}; #endif its all very nice, the only problem is that i now get 708 errors (yes 708), about MY_STRING and MY_NUMBER allready being defined in another object. for example: ClientEditDlg.obj : error LNK2005: "char const * const COLHT_VLV_NOTES" (?COLHT_VLV_NOTES@@3PBDB) already defined in Boletaje.obj onfigSheet.obj : error LNK2005: "char const * const IF_FILENAME" (?IF_FILENAME@@3PBDB) already defined in Boletaje.obj please notice that i DID include guards on the appconsts.h file, i tried removing all the #includes to appconsts.h file, and just including it in my stdafx.h file, but no luck, and since this is a WTL project, i dont have any other file (besides stdafx.h) that gets included everywhere. Can someone help me out? ***UPDATE*** mhh, i get it now, i should declare the consts in some .cpp file (say where my winmain()is), and then op appconsts.h i should do like this: extern const TCHAR* MY_STRING = _T("a string"); extern const int MY_NUMBER = 100; enum MY_ENUM{En1=0, En2, En3}; is this correct? if so, wouldnt be easyer to just use #define instead of const? i mean, MS uses it! for example in winuser.h: // ShowWindow() Commands #define SW_HIDE 0 #define SW_SHOWNORMAL 1 #define SW_NORMAL 1 #define SW_SHOWMINIMIZED 2 #define SW_SHOWMAXIMIZED 3 #define SW_MAXIMIZE 3 ... what you guys think?
When you change to
const
s, you are creating global variables. As such, you have to declare/define them differently. What's happening now is that a.cpp includes appconsts.h and seesMY_STRING
is a global variable, soMY_STRING
(appropriately name-decorated) goes into a.obj. Then b.cpp comes along, includes appconsts.h, and seesMY_STRING
. Same thing happens,MY_STRING
goes into b.obj. When the linker runs, it collects the obj files into an executable, but sees the multiple definitions ofMY_STRING
, which breaks the ODR (one definition rule: each symbol must have exactly one definition). For a quick hack, add__declspec(selectany)
to the variable definitions. The real way to solve it is in the FAQ[^] --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- You cannot stop me with paramecium alone! -
When you change to
const
s, you are creating global variables. As such, you have to declare/define them differently. What's happening now is that a.cpp includes appconsts.h and seesMY_STRING
is a global variable, soMY_STRING
(appropriately name-decorated) goes into a.obj. Then b.cpp comes along, includes appconsts.h, and seesMY_STRING
. Same thing happens,MY_STRING
goes into b.obj. When the linker runs, it collects the obj files into an executable, but sees the multiple definitions ofMY_STRING
, which breaks the ODR (one definition rule: each symbol must have exactly one definition). For a quick hack, add__declspec(selectany)
to the variable definitions. The real way to solve it is in the FAQ[^] --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- You cannot stop me with paramecium alone! -
Thanks for your answer Michael, i updated the original message before i readed your reply (i guess i was updating it while you were adding the reply:), i would appreciate if you read the update and tell me what you think about using #define
That's still not exactly right. You don't initialize global variables in the header file, but in the .cpp file where they are defined. appconsts.h:
extern TCHAR* FOO;
appconsts.cpp:TCHAR* FOO = _T("Hello");
The Windows headers use#define
because the API is still a C interface, andconst
is not supported by all C compilers (it was officially added to C rather recently). --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- There is a saying in statistics that a million monkeys pounding on typewriters would eventually create a work of Shakespeare. Thanks to the Internet, we now know that this is not true. -
That's still not exactly right. You don't initialize global variables in the header file, but in the .cpp file where they are defined. appconsts.h:
extern TCHAR* FOO;
appconsts.cpp:TCHAR* FOO = _T("Hello");
The Windows headers use#define
because the API is still a C interface, andconst
is not supported by all C compilers (it was officially added to C rather recently). --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ ---- There is a saying in statistics that a million monkeys pounding on typewriters would eventually create a work of Shakespeare. Thanks to the Internet, we now know that this is not true.