Question

I have to implement a set_configuration API of signal processing device. This API should ensure that set of configuration provided by the user is legitimate (within expected range) before setting it. Moreover, configuration values are in discrete form.

I want to manipulate preprocessor directives in C to implement this conditional check; if/else takes lot of lines to implement.

One possible solution I think of is following;

typedef enum {VERY_LOW, LOW, HIGH, VERY_HIGH} config_first;

typedef enum {VERY_SHORT, SHORT, LONG, VERY_LONG} config_second;

typedef enum {SQUARE, CIRCLE, TRIANGLE, RECTANGLE} config_third;

typedef enum {GREEN, WHITE, YELLOW, BROWN, GREY} config_fourth;

typedef enum {WOOD, IRON, STEEL} config_fourth;

typedef enum {SWIM, FLY, RUN, WALK} config_fifth;

set_configuration(config_first first, config_second second, config_third third, config_fourth fourth, config_fifth fifth)

My question is, Is there any way I can combine all these configurations to one enumeration and make it as follows:

set_configuration(config_set config)

where config_set is a preprocessor directive.

Was it helpful?

Solution

You can do it with bit fields, like this:

typedef enum {VERY_LOW   = 0x00,
              LOW        = 0x01,
              HIGH       = 0x02,
              VERY_HIGH  = 0x03,
              VERY_SHORT = 0x00 << 2,
              SHORT      = 0x01 << 2,
              LONG       = 0x02 << 2,
              VERY_LONG  = 0x02 << 2,
              SQUARE     = 0x00 << 4,
              CIRCLE     = 0x01 << 4,
              TRIANGLE   = 0x02 << 4,
              RECTANGLE  = 0x03 << 4,
              GREEN      = 0x00 << 6,
              WHITE      = 0x01 << 6,
              YELLOW     = 0x02 << 6,
              BROWN      = 0x03 << 6,
              GREY       = 0x04 << 6,
              WOOD       = 0x00 << 9,
              IRON       = 0x01 << 9,
              STEEL      = 0x02 << 9,
              SWIM       = 0x00 << 11,
              FLY        = 0x01 << 11,
              RUN        = 0x02 << 11,
              WALK       = 0x03 << 11
} config;

set_configuration(config_set config);

and then set your configuration by ORing together the fields, e.g.

set_configuration(LOW | SHORT | CIRCLE | WHITE | IRON | FLY);

Maintaining the enum can be a pain, as you manually have to ensure that fields do not overlap etc. It can be improved by using multiple enums for each field value and shift - this adds more clutter but potentially makes maintenance easier.

[Note: you mention using the preprocessor in your question - it's not clear exactly what you are trying to achieve, but if you need to do compile-time checks rather than run-time checks then you can use the same technique as above, but replace the enums with #defines.]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top