Home > Mobile >  Using C defines to simplify constant definitions?
Using C defines to simplify constant definitions?

Time:10-19

I have the following defines:

#define M(x) ( ((uint64_t) 1) << (x) )
#define Mx  M(0)
#define My  M(1)
#define Mz  M(2)

Quite often I need to rearrange the order of Mx, My, Mz, for example:

#define My  M(0)
#define Mz  M(1)
#define Mx  M(2)

How would I make this more generic in a sense of not having to correct M(0/1/2) every time, but just shuffle the lines?

#define POS ... 

#define My  M(POS)
#define Mz  M(POS)
#define Mx  M(POS)

CodePudding user response:

You could use an extra macro in between that will select an appropriate argument from the permutation. The permutation would be a macro itself that can be undefined and redefined.

#define NTH0(a0,a1,a2) a0
#define NTH1(a0,a1,a2) a1
#define NTH2(a0,a1,a2) a2
#define NTH(n, perm) NTH ## n (perm)

#define Mx  M(NTH(0, PERM))
#define My  M(NTH(1, PERM))
#define Mz  M(NTH(2, PERM))

#define PERM 1,2,3

Mx
My
Mz

#undef PERM
#define PERM 3,2,1

Mx
My
Mz

When compiled with gcc -E it expands to:

M(1)
M(2)
M(3)




M(3)
M(2)
M(1)

CodePudding user response:

The best solution might be to solve this with version control or #ifdef switches rather than function-like macros. Or perhaps generate the C source through a script.

Otherwise, the standard pre-processor way to list stuff while avoiding code repetition is "X macros", where you only need to change the values in a single place (called M_LIST in this example):

#include <stdio.h>
#include <inttypes.h>

#define M_LIST(X) \
  X(x,0)          \
  X(y,1)          \
  X(z,2)          \

#define M_enum(symbol,val) M##symbol##_bit = val,
enum { M_LIST(M_enum) };

#define M(symbol) ( 1ull << (M##symbol##_bit) )

int main (void)
{
  printf("%.16"PRIx64"\n", M(x));
  printf("%.16"PRIx64"\n", M(y));
  printf("%.16"PRIx64"\n", M(z));
}

Here a temporary enum is created, which will expand to: enum { Mx_bit = 0, My_bit = 1, Mz_bit = 2, }. These constants aren't used directly by your program, but only through the macro M.

  •  Tags:  
  • c
  • Related