简体   繁体   中英

Passing an enum string (not value) to a macro

So I had this query wherein say I have an enum and a struct that look like these,

enum fields {
   field_1,
   field_2
};

struct my_struct {
    int field_1;
    int field_2;
};

My specific need is, given the enum with the names of the structure members (field_1, field_2 etc) I should be able to generate a macro which can set the structure member to a given value.

#define my_macro (__a, __field) \
__a.__field = 1;

So is there a way to call my_macro like this:

struct my_struct b;
/* extract members of enum as string literals  */
my_macro(b, /*field name from the enum */);

Few other posts detailing usage of boost macros helps me extract the enum members as strings ( How to convert an enum type variable to a string? ). Issue is with passing it in the appropriate manner to the macro.

It should work the way it is. Macros are processed before compilation, while the code is still code, and they result in code generation.

Your macro #define my_macro(__a, __field) __a.__field = 1; will cause any entry like my_macro(x, y) to be transformed into xy = 1; , literally, before its handed to the compiler.

If you do something like my_macro(1+1, "test") , it will generate the code 1+1."test" = 1; and will create a compile error. Thats how simple macros are.

Thats why macro parameters are often enclosed by () to make sure it will work the way it was intented, if you don't do that things like this can happen:

#define div_by_100(a) a / 100

printf("%d\n", div_by_100(1000)); // will print 10
printf("%d\n", div_by_100(500 + 500)); // will print 505

This happens because order of operations is resolved at compile time, after the macros have been resolved.

Notice that, because macros are resolved before compilation, they are not a runtime solution. If this enum value is not explict in the code, macros won't help you at all. You will have to write a routing function that will assign a value to each member of this class/struct depending on what enum value was given. Example:

void route(struct farm* s, enum animals e)
{
    switch (e)
    {
        case cow:
            s->cow = 1;
            break;
        case duck:
            s->duck = 1;
            break;
        case horse:
            s->horse = 1;
            break;
        case goat:
            s->goat = 1;
            break;
    }
}

It depends on the way your mechanism of turning an enum to a string works. Your macro should work as long as that mechanism is still a macro that gets replaced by the preprocessor. That's the issue. Your macro should otherwise work properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM