Reputation: 17577
When i include the "xmacro.h" in header file which is used by multiple header files i get linking error:
Error LNK2005: "char const * * iD_Strings" (?iD_Strings@@3PAPBDA) already defined in header_file.obj
1.//"xmacro.h"
2.
3.// (1) Define code generating macro
4.
5. #ifndef XMACRO_H
6. #define XMACRO_H
7.
8. #define GENERATE_IDS \
9. X(_Name, "/Name") \
10. X(_ID, "/ID")
11.
12. // (2) Define X-Macro for generating enum members
13.
14. #define X(id, idString) id,
15. enum IDs
16. {
17. ID_LOWERBOUND = -1,
18. GENERATE_IDS
19. NUM_IDS
20. };
21. #undef X
22.
23. // (3) Define X-Macro for generating string names
24.
25. #define X(id, idString) idString,
26. const char* iD_Strings[] =
27. {
28. GENERATE_IDS
29. NULL
30. };
31. #undef X
32.
33. #endif
it generates an error when i define X-Macro for generating string names at line 23. how would i use a single macro without redefining it?
Upvotes: 1
Views: 977
Reputation: 21
A better way to do X-Macros (which I've always called list macros) is to pass the operator as a parameter to the list, then you can keep multiple "operators" around at the same time:
#define GENERATE_IDS(_) \
_(Name) \
_(Id)
enum IDs
{
ID_LOWERBOUND = -1,
#define MK_ID_ENUM(n) _##n,
GENERATE_IDS(MK_ID_ENUM)
NUM_IDS
}
const char* iD_Strings[] =
{
#define MK_ID_STRING(n) "/" #n,
GENERATE_IDS(MK_ID_STRING)
NULL
};
Note you still have to declare the identifiers uniquely, but the invocation of the GENERATE_IDS() macro to declare objects really belongs in a .c/.c++ body and not a header anyway.
Upvotes: 2
Reputation: 182000
Your header file contains the definition of iD_Strings
. When you include it from different source files, it gets linked in multiple times. That results in a conflict even if the definitions are identical.
You could declare iD_Strings
as static
(the C way) or wrap it in an anonymous namespace (the C++ way) to get around this problem.
Upvotes: 3