Take the 2-minute tour ×

I have this macro code, which allows me to define both a C enum and a list of the enumerated names as strings using one construct. It prevents me from having to duplicate enumerator names (and possibly introducing errors for large lists).

  F(0, Item1) \
  F(5, Item2) \
  F(15, Item3) \
  F(63, ItemN)


enum Items {
  #define ITEM_ENUM_DEFINE(id, name) name = id,

which, when expanded, should produce:

enum Items {
  Item1 = 0,
  Item2 = 5,
  Item3 = 15,
  ItemN = 63,

In the implementation file, I have this code:

const char* itemNames[TOTAL_ITEMS];
int iter = 0;

#define ITEM_STRING_DEFINE(id, name) itemNames[iter++] = #name;

which, when expanded, produces:

itemNames[iter++] = "Item1";
itemNames[iter++] = "Item2";
itemNames[iter++] = "Item3";
itemNames[iter++] = "ItemN";

I'd like to know how many enumerator items I've created in this fashion and be able to pass it to compile-time arrays. In the example above, this would be determining that TOTAL_ITEMS = N at compile-time. Is it possible to count macro invocations in this way?

I've seen mention of a non-standard COUNTER macro, similar to the FILE and LINE macros, but I'm hoping there is a more standard way.

Would also be interested in hearing if there is a better way to achieve this without having to use macros.

share|improve this question
Why do you need both the enum and the array of strings? –  Philip Dec 29 '11 at 6:21
It seems to comes up pretty frequently in my line of work. An example would be a state machine where the states are enumerated, and a front-end GUI displays the name of the current state. Its convenient to define it only once, and makes it easier for other developers who wish to add new states. –  Eyal Dec 29 '11 at 18:39

5 Answers 5

up vote 6 down vote accepted

The following should work:

#define ITEM_STRING_DEFINE(id, name) #name, // note trailing comma
const char *itemNames[] = {

#define TOTAL_ITEMS (sizeof itemNames / sizeof itemNames[0])

Edit: Thank you to Raymond Chen for noting we don't have to worry about the unnecessary final comma in the list. (I had been misremenbering the problem for enums with strict C89 compilers, as in Is the last comma in C enum required?.)

share|improve this answer
You don't need to eat the trailing comma. A trailing comma is legal and ignored. –  Raymond Chen Dec 28 '11 at 23:51
Regarding the final unnecessary comma, I seem to recall that the SGI Irix compiler would issue a non-suppressible warning about it, which forced me to always omit it. –  Joseph Quinsey Dec 29 '11 at 0:22


You could always use a scripting language such as ruby or python to generate .c and .h files for you. If you do it well, you can integrate your script into your Makefile.

share|improve this answer
I generally dislike approaches that add yet another language to the build requirements. –  Alex Dec 28 '11 at 23:53

I know this isn't a complete answer. You can create a macro around something like this.

#include <stdio.h>

const char * array[] = {
  "arr1", "arr2", "arr3", "arr4"

int main (int argc, char **argv)$
  printf("%d\n", sizeof(array)/sizeof(const char *));

If you can modify your enum so it has continous elements you can do sth like this (from Boost)

enum { A=0,B,C,D,E,F,N };
const char arr[N]; // can contain a character for each enum value
share|improve this answer

You can use the same technique to count the invocations.

enum itemscounter  { 
  #define ITEM_ENUM_DEFINE(id, name) name##counter,
share|improve this answer
I accepted the above answer, but think this is a pretty good (and clever) approach as well. Thanks! –  Eyal Dec 29 '11 at 18:33

See the suggestions Mu Dynamics 'Enums, Strings and Laziness'; these are at least related to what you're after.

Otherwise, look at the Boost Preprocessor collection (which is usable with the C preprocessor as well as the C++ preprocessor).

share|improve this answer

Your Answer


