最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In C, Is there a way to know where an enum value came from? - Stack Overflow

programmeradmin5浏览0评论

Lets say we have two enums. One for letters and one for numbers (This is just an example, I am not actually planning on using an enum to indicate letters and numbers)

typedef enum
{
    a,
    b,
    c,
    d,
    .
    .
    .
}te_letters;


typedef enum
{
    one,
    two,
    three,
    .
    .
    .
}te_numbers;

Then to interpret the info, I need a separate function for each enum. Here's a "main" that prints stuff.

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_print(a);//prints "a"
    numeric_print(one);//prints "1"
}

I need alpha_print and numeric_print.

And if I misplace the functions due to human error, it gets misinterpreted

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_print(one);//prints "a"
    numeric_print(a);//prints "1"
}

I'd like to have do something like the following where I only need one function

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_numeric_print(a);//prints "a"
    alpha_numeric_print(one);//prints "1"
}

I experimented with Preprocessor macros to detect if an enum exist. But that didnt work. So right now I am making a python tool for my very specific work to help check me and make sure I dont mismatch anything.

Does anyone have any ideas as to how I might detect where an enum came from?

(and if you are curious, I want this because we store info in different places in my work's embedded application. Some on flash, some on EEPROM, some in different formats. and the existing structures and enums dont have any identifying data that I can use to know that I'm reading the wrong area)

Lets say we have two enums. One for letters and one for numbers (This is just an example, I am not actually planning on using an enum to indicate letters and numbers)

typedef enum
{
    a,
    b,
    c,
    d,
    .
    .
    .
}te_letters;


typedef enum
{
    one,
    two,
    three,
    .
    .
    .
}te_numbers;

Then to interpret the info, I need a separate function for each enum. Here's a "main" that prints stuff.

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_print(a);//prints "a"
    numeric_print(one);//prints "1"
}

I need alpha_print and numeric_print.

And if I misplace the functions due to human error, it gets misinterpreted

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_print(one);//prints "a"
    numeric_print(a);//prints "1"
}

I'd like to have do something like the following where I only need one function

void main()
{
    uint8_t test1 = a;//numeric value is 1;
    uint8_t test2 = one;//numeric value is 1;

    alpha_numeric_print(a);//prints "a"
    alpha_numeric_print(one);//prints "1"
}

I experimented with Preprocessor macros to detect if an enum exist. But that didnt work. So right now I am making a python tool for my very specific work to help check me and make sure I dont mismatch anything.

Does anyone have any ideas as to how I might detect where an enum came from?

(and if you are curious, I want this because we store info in different places in my work's embedded application. Some on flash, some on EEPROM, some in different formats. and the existing structures and enums dont have any identifying data that I can use to know that I'm reading the wrong area)

Share Improve this question asked Jan 21 at 15:37 ZenoZeno 1351 gold badge2 silver badges8 bronze badges 20
  • 2 What parameters are declared for alpha_print? – i486 Commented Jan 21 at 15:40
  • 4 "//numeric value is 1;" Except it is zero in both cases. – Lundin Commented Jan 21 at 15:41
  • 4 Anyway I think you might be looking for something similar to How to create type safe enums? My answer there with a macro utilizing a dummy union would solve the problem here I think. – Lundin Commented Jan 21 at 15:45
  • 1 Don't add an "EDIT:", edit the question to be coherent from top to bottom as if you had always written it like that. Add solutions as answers instead. – mkrieger1 Commented Jan 21 at 16:08
  • 2 @Zeno To me it is still unclear what kind of errors you want to detect or avoid. The last paragraph of your question made me think that you might read something from a wrong location or forward data in some wrong way. Some more realistic and more detailed example might help to provide better suggestions. – Bodo Commented Jan 21 at 16:50
 |  Show 15 more comments

2 Answers 2

Reset to default 1

C/C++ compilers don't keep track of the source of data once it's been converted. You could do something like this to embed the source directly into the data type:

typedef enum {
   a=0,
   b,
   ... 
} te_letter;

typedef enum {
   one=0x100,
   two,
   ...
} te_numeric;

alpha_numberic_print(uint16 val) {
   if (val & 0x100)
      numeric_print(val-0x100)
   else
      alpha_print(val)
}

There is no builtin mechanism to do this, so you have to use some hacky solution for this. You could use a a tagged enum.


One solution is to use a struct. ex.:
typedef struct {
    enum {LETTER, NUMBER} type;
    int value;
} enum_value;

void print_enum_value(enum_value val) {
    if (val.type == LETTER) {
         // ...
    } else if (val.type == NUMBER) {
         // ...
    }
}

Other is to use macros and embedding the type via bit manipulation

enum {
    NUMBER,
    LETTER
} type;

#define TAGGED_ENUM(type, value) (((type) << 16) | (value))

#define GET_TYPE(value)  ((value) >> 16)
#define GET_VALUE(value) ((value) & 0xFFFF)

void print_tagged_value(int tagged_value) {
    int type = GET_TYPE(tagged_value);
    int value = GET_VALUE(tagged_value);

    if (type == LETTER) {
        // ...
    } else if (type == NUMBER) {
        // ...
    }
}

int main() {
    int tagged_letter = TAGGED_ENUM(TYPE_LETTER, a);
    print_tagged_value(tagged_letter);
}
发布评论

评论列表(0)

  1. 暂无评论