views:

1042

answers:

2

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?

+14  A: 

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
A couple of people downvoted this. I'd be interested to know what they find objectionable about it.
Kristopher Johnson
+1  A: 

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
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