Preprocessor tricks: foreach macro

GNU_Compiler_Collection_logo

Overview

Regularly, in C based projects we use enumerations for different purposes. And often it is useful to have a possibility to convert enum value into a string to provide a human-readable output in the message. A straightforward solution would be to define an array with strings that will accompany the enum. But this solution has a drawback during maintaining phase as far as a developer has to be careful to update both the enum and the array simultaneously.

Solution

The aforementioned inconvenience can be solved by using the preprocessor capabilities. The idea behind the trick is to call one macro inside another. And the purpose of the macros is to build both the enumeration and the array based on one common macro content.

First, define the enum values and strings.
#define foreach_test_error \
_ (NONE, "no error") \
_ (UNKNOWN_PROTOCOL, "unknown") \
_ (UNKNOWN_CONTROL, "control")

Second, define the error messages array.
static char *error_strings[] = {
#define _(f,s) s,
foreach_test_error
#undef _
};

Third, define the enum of errors.
typedef enum
{
#define _(f,s) TEST_ERROR_##f,
foreach_error
#undef _
TEST_N_ERROR,
} error_t;

References

Learning DPDK: Inlining

To_Inline_or_not_to_Inline_Dia_01Overview

Inlining method can help to mitigate the following:

  1. Function call overhead;
  2. Pipeline stall.

It is advised to apply the method for the following types of routines:

  1. Trivial and small functions used as accessors to data or wrappers around another function;
  2. Big functions called quite regularly but not from many places.

Solution

A modern compiler uses heuristics to decide which functions need to be inlined. But it is always better to give it a hint using the following keywords.

static inline

Moreover to make a decision instead of the gcc compiler the following attribute should be used.

__attribute__((always_inline))

References