1

Is their a simple way to initialize a typedef enum to a string in C? For example, I would like to initialize the following typedef enum to its string counterpart:

typedef enum 
{ 
    ADD, 
    PLUS, MINUS, MUL, DIV, MOD, 
    AND, OR, NOT, 
    BROKEN_FOO
} foo;

Just like how one initializes any string in C (char* foo = "+"), how could I initialize each member of foo to its string counterpart? e.g. MINUS = "-" etc. I know that each member is represented as an int, but I'm not sure how to go about this, given that each member is represented as an int.

J_code
  • 356
  • 1
  • 5
  • 17
  • `"+"` is a string literal, not an int. `'+'`, in contrast, is an int. – Stephan Lechner Jun 24 '18 at 21:01
  • 2
    You could do `typedef enum {ADD='+', PLUS='+', MINUS='-', ...} foo;` to initialize the constants to integral values (note the single quotes.) You could also use a more elaborate mapping of `enum` values to strings if strings are a requirement: `typedef enum { ... } foo; const char *foo_string[] = { [ADD]="+", [PLUS]="+", [MINUS]="-", ... };` is one way, and you can use `foo_string[ADD]` to get `"+"`. Code generators such as GNU AutoGen exist to do this for you, so you don't need to worry about mapping something incorrectly. You cannot, however, set an `enum` value to a string directly. –  Jun 24 '18 at 21:09

2 Answers2

2

Enums are represented as integral values, so you cannot assign values of type char*. You could, however, maintain a separate array of strings corresponding to the enum-values:

typedef enum
{
    ADD = 0,
    PLUS = 1, MINUS = 2, MUL = 3, DIV = 4, MOD = 5,
    AND = 6, OR = 7, NOT = 8,
    BROKEN_FOO = 9
} foo;

const char* fooStrings[] = {
   "+","+","-","*","/","%","&","|","^",NULL
};

int main() {

    printf("OR (%d): %s\n", OR, fooStrings[OR]);
}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • *Enums are represented as integral values, so you cannot assign values of type `char*`.* Ooooh, a truly evil hack just came to mind. I'll refrain from sharing it lest I be doomed to the outer reaches of oblivion for all eternity by programmers who have to fix problems arising from it.... ;-) – Andrew Henle Jun 24 '18 at 21:48
  • 2
    Improvement suggestion: I would let enum values be autogenerated, and then [check that the element count matches with the array using static assertion.](https://stackoverflow.com/a/10465622/694733) – user694733 Jun 25 '18 at 07:12
2

An alternative that ensures that the symbol aligns with the enum,

#include <stdio.h>

#define OPS \
    X(ADD, +), \
    X(PLUS, +), \
    X(MINUS, -), \
    X(MUL, *), \
    X(DIV, /), \
    X(MOD, %), \
    X(AND, &), \
    X(OR, |), \
    X(NOT, ^)

#define X(a, b) a
enum Foo { OPS };
#undef X

#define X(a, b) #b
static const char *const foo_strings[] = { OPS };
#undef X

static const unsigned foo_size = sizeof foo_strings / sizeof *foo_strings;

#define X(a, b) #a
static const char *const foo_title[] = { OPS };
#undef X

int main(void) {
    unsigned foo;
    for(foo = 0; foo < foo_size; foo++)
        printf("%s: %s\n", foo_title[foo], foo_strings[foo]);
    printf("DIV: %s.\n", foo_strings[DIV]);
    return 0;
}
Neil
  • 1,767
  • 2
  • 16
  • 22