16

Say you want to generate a matched list of identifiers and strings

enum
{
NAME_ONE,
NAME_TWO,
NAME_THREE
};

myFunction(NAME_ONE, "NAME_ONE");
myFunction(NAME_TWO, "NAME_TWO");
myFunction(NAME_THREE, "NAME_THREE");

..without repeating yourself, and without auto-generating the code, using C/C++ macros

Initial guess:

You could add an #include file containing

myDefine(NAME_ONE)
myDefine(NAME_TWO)
myDefine(NAME_THREE)

Then use it twice like:

#define myDefine(a) a,
enum {
#include "definitions"
}
#undef myDefine

#define myDefine(a) myFunc(a, "a");
#include "definitions"
#undef myDefine

but #define doesn't let you put parameters within a string?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
OJW
  • 4,514
  • 6
  • 40
  • 48

2 Answers2

28

For your second #define, you need to use the # preprocessor operator, like this:

#define myDefine(a) myFunc(a, #a);

That converts the argument to a string.

Kristopher Johnson
  • 81,409
  • 55
  • 245
  • 302
4

Here's a good way to declare name-list:

#define FOR_ALL_FUNCTIONS(F)\
  F(NameOne)\
  F(NameTwo)\
  F(NameThree)\

#define DECLARE_FUNCTION(N)\
    void N();

#define IMPLEMENT_FUNCTION(N)\
    void N(){}

FOR_ALL_FUNCTIONS(DECLARE_FUNCTION);
FOR_ALL_FUNCTIONS(IMPLEMENT_FUNCTION);

This way this name-list can be re-used multiple times. I have used it for prototyping new language features, although never ended up using them. So, if nothing else, they were a great way to find dead-ends in own inventions. I wonder if it's because what they say: "macros are bad"... :)

AareP
  • 2,355
  • 3
  • 21
  • 28
  • 1
    Great to see someone else is using the macro name passing as well. I find this technique very powerful and useful. Shameless plug: http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511 – Suma Oct 14 '08 at 19:41